@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,27 +4,36 @@ 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';
11
+ import { UserInfoEngine } from '@memberjunction/core-entities';
10
12
  import { BaseFormComponent } from '@memberjunction/ng-base-forms';
11
13
  import { RegisterClass } from '@memberjunction/global';
12
14
  import { SharedService } from '@memberjunction/ng-shared';
13
15
  import { TestSuiteRunFormComponent } from '../../generated/Entities/TestSuiteRun/testsuiterun.form.component';
16
+ import { TagsHelper, calculateEvaluationMetrics, normalizeExecutionStatus, getNeedsReviewItems } from '@memberjunction/ng-testing';
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";
20
+ import * as i3 from "@memberjunction/ng-testing";
21
+ import * as i4 from "@angular/common";
22
+ import * as i5 from "@angular/forms";
23
+ import * as i6 from "@progress/kendo-angular-dialog";
24
+ import * as i7 from "@progress/kendo-angular-buttons";
25
+ import * as i8 from "./entity-link-pill.component";
26
+ const _c0 = () => [1, 2, 3, 4, 5];
27
+ const _c1 = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
19
28
  function TestSuiteRunFormComponentExtended_div_2_Template(rf, ctx) { if (rf & 1) {
20
29
  const _r1 = i0.ɵɵgetCurrentView();
21
- i0.ɵɵelementStart(0, "div", 42)(1, "a", 43);
30
+ i0.ɵɵelementStart(0, "div", 61)(1, "a", 62);
22
31
  i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_2_Template_a_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openTestSuite()); });
23
- i0.ɵɵelement(2, "i", 44);
32
+ i0.ɵɵelement(2, "i", 63);
24
33
  i0.ɵɵtext(3);
25
34
  i0.ɵɵelementEnd();
26
- i0.ɵɵelement(4, "i", 45);
27
- i0.ɵɵelementStart(5, "span");
35
+ i0.ɵɵelement(4, "i", 64);
36
+ i0.ɵɵelementStart(5, "span", 65);
28
37
  i0.ɵɵtext(6);
29
38
  i0.ɵɵelementEnd()();
30
39
  } if (rf & 2) {
@@ -35,25 +44,140 @@ function TestSuiteRunFormComponentExtended_div_2_Template(rf, ctx) { if (rf & 1)
35
44
  i0.ɵɵtextInterpolate1("Run #", ctx_r1.record.ID.substring(0, 8), "");
36
45
  } }
37
46
  function TestSuiteRunFormComponentExtended_span_14_Template(rf, ctx) { if (rf & 1) {
38
- i0.ɵɵelementStart(0, "span", 46);
47
+ i0.ɵɵelementStart(0, "span", 66);
48
+ i0.ɵɵelement(1, "i", 67);
49
+ i0.ɵɵtext(2);
50
+ i0.ɵɵelementEnd();
51
+ } if (rf & 2) {
52
+ const ctx_r1 = i0.ɵɵnextContext();
53
+ i0.ɵɵadvance(2);
54
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.record.Environment, " ");
55
+ } }
56
+ function TestSuiteRunFormComponentExtended_span_15_Template(rf, ctx) { if (rf & 1) {
57
+ i0.ɵɵelementStart(0, "span", 68);
58
+ i0.ɵɵelement(1, "i", 69);
59
+ i0.ɵɵtext(2);
60
+ i0.ɵɵelementEnd();
61
+ } if (rf & 2) {
62
+ const ctx_r1 = i0.ɵɵnextContext();
63
+ i0.ɵɵadvance(2);
64
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.record.TriggerType, " ");
65
+ } }
66
+ function TestSuiteRunFormComponentExtended_button_18_Template(rf, ctx) { if (rf & 1) {
67
+ const _r3 = i0.ɵɵgetCurrentView();
68
+ i0.ɵɵelementStart(0, "button", 70);
69
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_button_18_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.reRunSuite()); });
70
+ i0.ɵɵelement(1, "i", 71);
71
+ i0.ɵɵtext(2, " Re-run Suite ");
72
+ i0.ɵɵelementEnd();
73
+ } }
74
+ function TestSuiteRunFormComponentExtended_div_96_div_4_span_1_Template(rf, ctx) { if (rf & 1) {
75
+ i0.ɵɵelementStart(0, "span", 82);
39
76
  i0.ɵɵtext(1);
40
77
  i0.ɵɵelementEnd();
78
+ } if (rf & 2) {
79
+ const tag_r5 = ctx.$implicit;
80
+ i0.ɵɵadvance();
81
+ i0.ɵɵtextInterpolate(tag_r5);
82
+ } }
83
+ function TestSuiteRunFormComponentExtended_div_96_div_4_Template(rf, ctx) { if (rf & 1) {
84
+ i0.ɵɵelementStart(0, "div", 80);
85
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_96_div_4_span_1_Template, 2, 1, "span", 81);
86
+ i0.ɵɵelementEnd();
87
+ } if (rf & 2) {
88
+ const ctx_r1 = i0.ɵɵnextContext(2);
89
+ i0.ɵɵadvance();
90
+ i0.ɵɵproperty("ngForOf", ctx_r1.tags);
91
+ } }
92
+ function TestSuiteRunFormComponentExtended_div_96_span_5_Template(rf, ctx) { if (rf & 1) {
93
+ i0.ɵɵelementStart(0, "span", 83);
94
+ i0.ɵɵtext(1, "No tags");
95
+ i0.ɵɵelementEnd();
96
+ } }
97
+ function TestSuiteRunFormComponentExtended_div_96_Template(rf, ctx) { if (rf & 1) {
98
+ const _r4 = i0.ɵɵgetCurrentView();
99
+ i0.ɵɵelementStart(0, "div", 72)(1, "div", 73)(2, "span", 74);
100
+ i0.ɵɵelement(3, "i", 75);
101
+ i0.ɵɵelementEnd();
102
+ i0.ɵɵtemplate(4, TestSuiteRunFormComponentExtended_div_96_div_4_Template, 2, 1, "div", 76)(5, TestSuiteRunFormComponentExtended_div_96_span_5_Template, 2, 0, "span", 77);
103
+ i0.ɵɵelementStart(6, "button", 78);
104
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_96_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.startEditingTags()); });
105
+ i0.ɵɵelement(7, "i", 79);
106
+ i0.ɵɵtext(8, " Add ");
107
+ i0.ɵɵelementEnd()()();
41
108
  } if (rf & 2) {
42
109
  const ctx_r1 = i0.ɵɵnextContext();
110
+ i0.ɵɵadvance(4);
111
+ i0.ɵɵproperty("ngIf", ctx_r1.tags.length > 0);
43
112
  i0.ɵɵadvance();
44
- i0.ɵɵtextInterpolate(ctx_r1.record.Environment);
113
+ i0.ɵɵproperty("ngIf", ctx_r1.tags.length === 0);
45
114
  } }
46
- function TestSuiteRunFormComponentExtended_span_15_Template(rf, ctx) { if (rf & 1) {
47
- i0.ɵɵelementStart(0, "span", 47);
115
+ function TestSuiteRunFormComponentExtended_div_97_span_7_Template(rf, ctx) { if (rf & 1) {
116
+ const _r7 = i0.ɵɵgetCurrentView();
117
+ i0.ɵɵelementStart(0, "span", 98);
48
118
  i0.ɵɵtext(1);
119
+ i0.ɵɵelementStart(2, "button", 99);
120
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_97_span_7_Template_button_click_2_listener() { const tag_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.removeTag(tag_r8)); });
121
+ i0.ɵɵelement(3, "i", 100);
122
+ i0.ɵɵelementEnd()();
123
+ } if (rf & 2) {
124
+ const tag_r8 = ctx.$implicit;
125
+ i0.ɵɵadvance();
126
+ i0.ɵɵtextInterpolate1(" ", tag_r8, " ");
127
+ } }
128
+ function TestSuiteRunFormComponentExtended_div_97_span_8_Template(rf, ctx) { if (rf & 1) {
129
+ i0.ɵɵelementStart(0, "span", 101);
130
+ i0.ɵɵtext(1, "No tags yet");
131
+ i0.ɵɵelementEnd();
132
+ } }
133
+ function TestSuiteRunFormComponentExtended_div_97_i_15_Template(rf, ctx) { if (rf & 1) {
134
+ i0.ɵɵelement(0, "i", 102);
135
+ } }
136
+ function TestSuiteRunFormComponentExtended_div_97_Template(rf, ctx) { if (rf & 1) {
137
+ const _r6 = i0.ɵɵgetCurrentView();
138
+ i0.ɵɵelementStart(0, "div", 84)(1, "div", 85)(2, "span", 86);
139
+ i0.ɵɵelement(3, "i", 75);
140
+ i0.ɵɵtext(4, " Edit Tags");
141
+ i0.ɵɵelementEnd()();
142
+ i0.ɵɵelementStart(5, "div", 87)(6, "div", 88);
143
+ i0.ɵɵtemplate(7, TestSuiteRunFormComponentExtended_div_97_span_7_Template, 4, 1, "span", 89)(8, TestSuiteRunFormComponentExtended_div_97_span_8_Template, 2, 0, "span", 90);
144
+ i0.ɵɵelementEnd();
145
+ i0.ɵɵelementStart(9, "div", 91)(10, "input", 92);
146
+ i0.ɵɵtwoWayListener("ngModelChange", function TestSuiteRunFormComponentExtended_div_97_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newTag, $event) || (ctx_r1.newTag = $event); return i0.ɵɵresetView($event); });
147
+ i0.ɵɵlistener("keyup.enter", function TestSuiteRunFormComponentExtended_div_97_Template_input_keyup_enter_10_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addTag()); });
148
+ i0.ɵɵelementEnd();
149
+ i0.ɵɵelementStart(11, "button", 93);
150
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_97_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addTag()); });
151
+ i0.ɵɵelement(12, "i", 79);
152
+ i0.ɵɵelementEnd()()();
153
+ i0.ɵɵelementStart(13, "div", 94)(14, "button", 95);
154
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_97_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.saveTags()); });
155
+ i0.ɵɵtemplate(15, TestSuiteRunFormComponentExtended_div_97_i_15_Template, 1, 0, "i", 96);
156
+ i0.ɵɵtext(16);
49
157
  i0.ɵɵelementEnd();
158
+ i0.ɵɵelementStart(17, "button", 97);
159
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_97_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelEditingTags()); });
160
+ i0.ɵɵtext(18, "Cancel");
161
+ i0.ɵɵelementEnd()()();
50
162
  } if (rf & 2) {
51
163
  const ctx_r1 = i0.ɵɵnextContext();
164
+ i0.ɵɵadvance(7);
165
+ i0.ɵɵproperty("ngForOf", ctx_r1.tags);
52
166
  i0.ɵɵadvance();
53
- i0.ɵɵtextInterpolate(ctx_r1.record.TriggerType);
167
+ i0.ɵɵproperty("ngIf", ctx_r1.tags.length === 0);
168
+ i0.ɵɵadvance(2);
169
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newTag);
170
+ i0.ɵɵadvance();
171
+ i0.ɵɵproperty("disabled", !ctx_r1.newTag.trim());
172
+ i0.ɵɵadvance(3);
173
+ i0.ɵɵproperty("disabled", ctx_r1.savingTags);
174
+ i0.ɵɵadvance();
175
+ i0.ɵɵproperty("ngIf", ctx_r1.savingTags);
176
+ i0.ɵɵadvance();
177
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.savingTags ? "Saving..." : "Save", " ");
54
178
  } }
55
- function TestSuiteRunFormComponentExtended_span_88_Template(rf, ctx) { if (rf & 1) {
56
- i0.ɵɵelementStart(0, "span", 48);
179
+ function TestSuiteRunFormComponentExtended_span_106_Template(rf, ctx) { if (rf & 1) {
180
+ i0.ɵɵelementStart(0, "span", 103);
57
181
  i0.ɵɵtext(1);
58
182
  i0.ɵɵelementEnd();
59
183
  } if (rf & 2) {
@@ -61,222 +185,1310 @@ function TestSuiteRunFormComponentExtended_span_88_Template(rf, ctx) { if (rf &
61
185
  i0.ɵɵadvance();
62
186
  i0.ɵɵtextInterpolate(ctx_r1.testRuns.length);
63
187
  } }
64
- function TestSuiteRunFormComponentExtended_div_94_Template(rf, ctx) { if (rf & 1) {
65
- i0.ɵɵelementStart(0, "div", 49)(1, "div", 50)(2, "div", 51);
66
- i0.ɵɵelement(3, "i", 10);
188
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_11_Template(rf, ctx) { if (rf & 1) {
189
+ i0.ɵɵelementStart(0, "div", 123)(1, "span", 124);
190
+ i0.ɵɵtext(2, "Avg Rating");
191
+ i0.ɵɵelementEnd();
192
+ i0.ɵɵelementStart(3, "span", 125);
193
+ i0.ɵɵtext(4);
194
+ i0.ɵɵelementEnd()();
195
+ } if (rf & 2) {
196
+ const ctx_r1 = i0.ɵɵnextContext(4);
197
+ i0.ɵɵadvance(4);
198
+ i0.ɵɵtextInterpolate1("", ctx_r1.evaluationMetrics.humanAvgRating.toFixed(1), "/10");
199
+ } }
200
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_12_span_5_Template(rf, ctx) { if (rf & 1) {
201
+ i0.ɵɵelementStart(0, "span", 130);
202
+ i0.ɵɵtext(1);
203
+ i0.ɵɵelementEnd();
204
+ } if (rf & 2) {
205
+ const ctx_r1 = i0.ɵɵnextContext(5);
206
+ i0.ɵɵadvance();
207
+ i0.ɵɵtextInterpolate1("", ctx_r1.evaluationMetrics.humanIncorrectCount, " incorrect");
208
+ } }
209
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_12_Template(rf, ctx) { if (rf & 1) {
210
+ i0.ɵɵelementStart(0, "div", 123)(1, "span", 124);
211
+ i0.ɵɵtext(2, "Correct");
212
+ i0.ɵɵelementEnd();
213
+ i0.ɵɵelementStart(3, "span", 128);
214
+ i0.ɵɵtext(4);
215
+ i0.ɵɵelementEnd();
216
+ i0.ɵɵtemplate(5, TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_12_span_5_Template, 2, 1, "span", 129);
217
+ i0.ɵɵelementEnd();
218
+ } if (rf & 2) {
219
+ const ctx_r1 = i0.ɵɵnextContext(4);
220
+ i0.ɵɵadvance(4);
221
+ i0.ɵɵtextInterpolate(ctx_r1.evaluationMetrics.humanCorrectCount);
222
+ i0.ɵɵadvance();
223
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.humanIncorrectCount > 0);
224
+ } }
225
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_13_Template(rf, ctx) { if (rf & 1) {
226
+ i0.ɵɵelementStart(0, "div", 131)(1, "span", 132);
227
+ i0.ɵɵelement(2, "i", 133);
228
+ i0.ɵɵtext(3);
229
+ i0.ɵɵelementEnd()();
230
+ } if (rf & 2) {
231
+ const ctx_r1 = i0.ɵɵnextContext(4);
232
+ i0.ɵɵadvance(3);
233
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.evaluationMetrics.humanPendingCount, " need review ");
234
+ } }
235
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_2_Template(rf, ctx) { if (rf & 1) {
236
+ i0.ɵɵelementStart(0, "div", 119)(1, "div", 120);
237
+ i0.ɵɵelement(2, "i", 121);
238
+ i0.ɵɵelementStart(3, "span");
239
+ i0.ɵɵtext(4, "Human Feedback");
240
+ i0.ɵɵelementEnd()();
241
+ i0.ɵɵelementStart(5, "div", 122)(6, "div", 123)(7, "span", 124);
242
+ i0.ɵɵtext(8, "Reviewed");
243
+ i0.ɵɵelementEnd();
244
+ i0.ɵɵelementStart(9, "span", 125);
245
+ i0.ɵɵtext(10);
246
+ i0.ɵɵelementEnd()();
247
+ i0.ɵɵtemplate(11, TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_11_Template, 5, 1, "div", 126)(12, TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_12_Template, 6, 2, "div", 126);
248
+ i0.ɵɵelementEnd();
249
+ i0.ɵɵtemplate(13, TestSuiteRunFormComponentExtended_div_118_div_19_div_2_div_13_Template, 4, 1, "div", 127);
250
+ i0.ɵɵelementEnd();
251
+ } if (rf & 2) {
252
+ const ctx_r1 = i0.ɵɵnextContext(3);
253
+ i0.ɵɵadvance(10);
254
+ i0.ɵɵtextInterpolate2("", ctx_r1.evaluationMetrics.humanReviewedCount, " / ", ctx_r1.evaluationMetrics.totalRuns, "");
255
+ i0.ɵɵadvance();
256
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.humanReviewedCount > 0);
257
+ i0.ɵɵadvance();
258
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.humanReviewedCount > 0);
259
+ i0.ɵɵadvance();
260
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.humanPendingCount > 0);
261
+ } }
262
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_3_div_11_Template(rf, ctx) { if (rf & 1) {
263
+ i0.ɵɵelementStart(0, "div", 123)(1, "span", 124);
264
+ i0.ɵɵtext(2, "Avg Score");
265
+ i0.ɵɵelementEnd();
266
+ i0.ɵɵelementStart(3, "span", 125);
267
+ i0.ɵɵtext(4);
268
+ i0.ɵɵelementEnd()();
269
+ } if (rf & 2) {
270
+ const ctx_r1 = i0.ɵɵnextContext(4);
271
+ i0.ɵɵadvance(4);
272
+ i0.ɵɵtextInterpolate1("", (ctx_r1.evaluationMetrics.autoAvgScore * 100).toFixed(0), "%");
273
+ } }
274
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_3_div_12_Template(rf, ctx) { if (rf & 1) {
275
+ i0.ɵɵelementStart(0, "div", 123)(1, "span", 124);
276
+ i0.ɵɵtext(2, "Pass Rate");
67
277
  i0.ɵɵelementEnd();
68
- i0.ɵɵelementStart(4, "div", 52)(5, "h2");
278
+ i0.ɵɵelementStart(3, "span", 125);
279
+ i0.ɵɵtext(4);
280
+ i0.ɵɵelementEnd()();
281
+ } if (rf & 2) {
282
+ const ctx_r1 = i0.ɵɵnextContext(4);
283
+ i0.ɵɵadvance(4);
284
+ i0.ɵɵtextInterpolate1("", ctx_r1.evaluationMetrics.autoPassRate.toFixed(0), "%");
285
+ } }
286
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_3_Template(rf, ctx) { if (rf & 1) {
287
+ i0.ɵɵelementStart(0, "div", 119)(1, "div", 120);
288
+ i0.ɵɵelement(2, "i", 134);
289
+ i0.ɵɵelementStart(3, "span");
290
+ i0.ɵɵtext(4, "Auto Evaluation");
291
+ i0.ɵɵelementEnd()();
292
+ i0.ɵɵelementStart(5, "div", 122)(6, "div", 123)(7, "span", 124);
293
+ i0.ɵɵtext(8, "Evaluated");
294
+ i0.ɵɵelementEnd();
295
+ i0.ɵɵelementStart(9, "span", 125);
296
+ i0.ɵɵtext(10);
297
+ i0.ɵɵelementEnd()();
298
+ i0.ɵɵtemplate(11, TestSuiteRunFormComponentExtended_div_118_div_19_div_3_div_11_Template, 5, 1, "div", 126)(12, TestSuiteRunFormComponentExtended_div_118_div_19_div_3_div_12_Template, 5, 1, "div", 126);
299
+ i0.ɵɵelementEnd()();
300
+ } if (rf & 2) {
301
+ const ctx_r1 = i0.ɵɵnextContext(3);
302
+ i0.ɵɵadvance(10);
303
+ i0.ɵɵtextInterpolate2("", ctx_r1.evaluationMetrics.autoEvaluatedCount, " / ", ctx_r1.evaluationMetrics.totalRuns, "");
304
+ i0.ɵɵadvance();
305
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.autoEvaluatedCount > 0);
306
+ i0.ɵɵadvance();
307
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.autoEvaluatedCount > 0);
308
+ } }
309
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_4_div_16_span_3_Template(rf, ctx) { if (rf & 1) {
310
+ i0.ɵɵelementStart(0, "span", 138);
311
+ i0.ɵɵtext(1);
312
+ i0.ɵɵelementEnd();
313
+ } if (rf & 2) {
314
+ const ctx_r1 = i0.ɵɵnextContext(5);
315
+ i0.ɵɵadvance();
316
+ i0.ɵɵtextInterpolate1("", ctx_r1.evaluationMetrics.execErrorCount, " errors");
317
+ } }
318
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_4_div_16_span_4_Template(rf, ctx) { if (rf & 1) {
319
+ i0.ɵɵelementStart(0, "span", 139);
320
+ i0.ɵɵtext(1);
321
+ i0.ɵɵelementEnd();
322
+ } if (rf & 2) {
323
+ const ctx_r1 = i0.ɵɵnextContext(5);
324
+ i0.ɵɵadvance();
325
+ i0.ɵɵtextInterpolate1("", ctx_r1.evaluationMetrics.execTimeoutCount, " timeouts");
326
+ } }
327
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_4_div_16_Template(rf, ctx) { if (rf & 1) {
328
+ i0.ɵɵelementStart(0, "div", 123)(1, "span", 124);
329
+ i0.ɵɵtext(2, "Issues");
330
+ i0.ɵɵelementEnd();
331
+ i0.ɵɵtemplate(3, TestSuiteRunFormComponentExtended_div_118_div_19_div_4_div_16_span_3_Template, 2, 1, "span", 136)(4, TestSuiteRunFormComponentExtended_div_118_div_19_div_4_div_16_span_4_Template, 2, 1, "span", 137);
332
+ i0.ɵɵelementEnd();
333
+ } if (rf & 2) {
334
+ const ctx_r1 = i0.ɵɵnextContext(4);
335
+ i0.ɵɵadvance(3);
336
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.execErrorCount > 0);
337
+ i0.ɵɵadvance();
338
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.execTimeoutCount > 0);
339
+ } }
340
+ function TestSuiteRunFormComponentExtended_div_118_div_19_div_4_Template(rf, ctx) { if (rf & 1) {
341
+ i0.ɵɵelementStart(0, "div", 119)(1, "div", 120);
342
+ i0.ɵɵelement(2, "i", 135);
343
+ i0.ɵɵelementStart(3, "span");
344
+ i0.ɵɵtext(4, "Execution");
345
+ i0.ɵɵelementEnd()();
346
+ i0.ɵɵelementStart(5, "div", 122)(6, "div", 123)(7, "span", 124);
347
+ i0.ɵɵtext(8, "Completed");
348
+ i0.ɵɵelementEnd();
349
+ i0.ɵɵelementStart(9, "span", 125);
350
+ i0.ɵɵtext(10);
351
+ i0.ɵɵelementEnd()();
352
+ i0.ɵɵelementStart(11, "div", 123)(12, "span", 124);
353
+ i0.ɵɵtext(13, "Success Rate");
354
+ i0.ɵɵelementEnd();
355
+ i0.ɵɵelementStart(14, "span", 125);
356
+ i0.ɵɵtext(15);
357
+ i0.ɵɵelementEnd()();
358
+ i0.ɵɵtemplate(16, TestSuiteRunFormComponentExtended_div_118_div_19_div_4_div_16_Template, 5, 2, "div", 126);
359
+ i0.ɵɵelementEnd()();
360
+ } if (rf & 2) {
361
+ const ctx_r1 = i0.ɵɵnextContext(3);
362
+ i0.ɵɵadvance(10);
363
+ i0.ɵɵtextInterpolate2("", ctx_r1.evaluationMetrics.execCompletedCount, " / ", ctx_r1.evaluationMetrics.totalRuns, "");
364
+ i0.ɵɵadvance(5);
365
+ i0.ɵɵtextInterpolate1("", ctx_r1.evaluationMetrics.execSuccessRate.toFixed(0), "%");
366
+ i0.ɵɵadvance();
367
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics.execErrorCount > 0 || ctx_r1.evaluationMetrics.execTimeoutCount > 0);
368
+ } }
369
+ function TestSuiteRunFormComponentExtended_div_118_div_19_Template(rf, ctx) { if (rf & 1) {
370
+ i0.ɵɵelementStart(0, "div", 116)(1, "div", 117);
371
+ i0.ɵɵtemplate(2, TestSuiteRunFormComponentExtended_div_118_div_19_div_2_Template, 14, 5, "div", 118)(3, TestSuiteRunFormComponentExtended_div_118_div_19_div_3_Template, 13, 4, "div", 118)(4, TestSuiteRunFormComponentExtended_div_118_div_19_div_4_Template, 17, 4, "div", 118);
372
+ i0.ɵɵelementEnd()();
373
+ } if (rf & 2) {
374
+ const ctx_r1 = i0.ɵɵnextContext(2);
375
+ i0.ɵɵadvance(2);
376
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showHuman);
377
+ i0.ɵɵadvance();
378
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showAuto);
379
+ i0.ɵɵadvance();
380
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showExecution);
381
+ } }
382
+ function TestSuiteRunFormComponentExtended_div_118_div_20_div_8_i_2_Template(rf, ctx) { if (rf & 1) {
383
+ i0.ɵɵelement(0, "i", 157);
384
+ } }
385
+ function TestSuiteRunFormComponentExtended_div_118_div_20_div_8_i_3_Template(rf, ctx) { if (rf & 1) {
386
+ i0.ɵɵelement(0, "i", 158);
387
+ } }
388
+ function TestSuiteRunFormComponentExtended_div_118_div_20_div_8_i_4_Template(rf, ctx) { if (rf & 1) {
389
+ i0.ɵɵelement(0, "i", 133);
390
+ } }
391
+ function TestSuiteRunFormComponentExtended_div_118_div_20_div_8_Template(rf, ctx) { if (rf & 1) {
392
+ const _r9 = i0.ɵɵgetCurrentView();
393
+ i0.ɵɵelementStart(0, "div", 147);
394
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_118_div_20_div_8_Template_div_click_0_listener() { const item_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleRunExpanded(item_r10.run.id)); });
395
+ i0.ɵɵelementStart(1, "div", 148);
396
+ i0.ɵɵtemplate(2, TestSuiteRunFormComponentExtended_div_118_div_20_div_8_i_2_Template, 1, 0, "i", 149)(3, TestSuiteRunFormComponentExtended_div_118_div_20_div_8_i_3_Template, 1, 0, "i", 150)(4, TestSuiteRunFormComponentExtended_div_118_div_20_div_8_i_4_Template, 1, 0, "i", 151);
397
+ i0.ɵɵelementEnd();
398
+ i0.ɵɵelementStart(5, "div", 152)(6, "span", 153);
399
+ i0.ɵɵtext(7);
400
+ i0.ɵɵelementEnd();
401
+ i0.ɵɵelementStart(8, "span", 154);
402
+ i0.ɵɵtext(9);
403
+ i0.ɵɵelementEnd()();
404
+ i0.ɵɵelementStart(10, "div", 155);
405
+ i0.ɵɵelement(11, "i", 156);
406
+ i0.ɵɵelementEnd()();
407
+ } if (rf & 2) {
408
+ const item_r10 = ctx.$implicit;
409
+ i0.ɵɵclassProp("high-priority", item_r10.priority === "high")("medium-priority", item_r10.priority === "medium");
410
+ i0.ɵɵadvance(2);
411
+ i0.ɵɵproperty("ngIf", item_r10.priority === "high");
412
+ i0.ɵɵadvance();
413
+ i0.ɵɵproperty("ngIf", item_r10.priority === "medium");
414
+ i0.ɵɵadvance();
415
+ i0.ɵɵproperty("ngIf", item_r10.priority === "low");
416
+ i0.ɵɵadvance(3);
417
+ i0.ɵɵtextInterpolate(item_r10.run.testName);
418
+ i0.ɵɵadvance(2);
419
+ i0.ɵɵtextInterpolate(item_r10.reason);
420
+ } }
421
+ function TestSuiteRunFormComponentExtended_div_118_div_20_div_9_Template(rf, ctx) { if (rf & 1) {
422
+ const _r11 = i0.ɵɵgetCurrentView();
423
+ i0.ɵɵelementStart(0, "div", 159)(1, "button", 97);
424
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_118_div_20_div_9_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.changeTab("runs")); });
425
+ i0.ɵɵtext(2);
426
+ i0.ɵɵelementEnd()();
427
+ } if (rf & 2) {
428
+ const ctx_r1 = i0.ɵɵnextContext(3);
429
+ i0.ɵɵadvance(2);
430
+ i0.ɵɵtextInterpolate1(" View all ", ctx_r1.needsReviewItems.length, " items ");
431
+ } }
432
+ function TestSuiteRunFormComponentExtended_div_118_div_20_Template(rf, ctx) { if (rf & 1) {
433
+ i0.ɵɵelementStart(0, "div", 140)(1, "div", 141)(2, "h3");
434
+ i0.ɵɵelement(3, "i", 142);
435
+ i0.ɵɵtext(4, " Needs Review");
436
+ i0.ɵɵelementEnd();
437
+ i0.ɵɵelementStart(5, "span", 143);
69
438
  i0.ɵɵtext(6);
439
+ i0.ɵɵelementEnd()();
440
+ i0.ɵɵelementStart(7, "div", 144);
441
+ i0.ɵɵtemplate(8, TestSuiteRunFormComponentExtended_div_118_div_20_div_8_Template, 12, 9, "div", 145)(9, TestSuiteRunFormComponentExtended_div_118_div_20_div_9_Template, 3, 1, "div", 146);
442
+ i0.ɵɵelementEnd()();
443
+ } if (rf & 2) {
444
+ const ctx_r1 = i0.ɵɵnextContext(2);
445
+ i0.ɵɵadvance(6);
446
+ i0.ɵɵtextInterpolate1("", ctx_r1.needsReviewItems.length, " items");
447
+ i0.ɵɵadvance(2);
448
+ i0.ɵɵproperty("ngForOf", ctx_r1.needsReviewItems.slice(0, 5));
449
+ i0.ɵɵadvance();
450
+ i0.ɵɵproperty("ngIf", ctx_r1.needsReviewItems.length > 5);
451
+ } }
452
+ function TestSuiteRunFormComponentExtended_div_118_div_21_Template(rf, ctx) { if (rf & 1) {
453
+ i0.ɵɵelementStart(0, "div", 160)(1, "div", 161);
454
+ i0.ɵɵelement(2, "i", 162);
455
+ i0.ɵɵelementStart(3, "span");
456
+ i0.ɵɵtext(4, "Suite execution in progress...");
457
+ i0.ɵɵelementEnd()();
458
+ i0.ɵɵelementStart(5, "div", 163);
459
+ i0.ɵɵelement(6, "i", 164);
460
+ i0.ɵɵtext(7, " Auto-refreshing every 5 seconds ");
461
+ i0.ɵɵelementEnd()();
462
+ } }
463
+ function TestSuiteRunFormComponentExtended_div_118_Template(rf, ctx) { if (rf & 1) {
464
+ i0.ɵɵelementStart(0, "div", 104)(1, "div", 105)(2, "div", 106);
465
+ i0.ɵɵelement(3, "i", 6);
70
466
  i0.ɵɵelementEnd();
71
- i0.ɵɵelementStart(7, "div", 53);
72
- i0.ɵɵtext(8);
467
+ i0.ɵɵelementStart(4, "div", 107)(5, "h2");
468
+ i0.ɵɵtext(6);
73
469
  i0.ɵɵelementEnd();
74
- i0.ɵɵelementStart(9, "div", 54);
470
+ i0.ɵɵelementStart(7, "div", 108)(8, "div", 109)(9, "span", 110);
75
471
  i0.ɵɵtext(10);
76
- i0.ɵɵelementEnd()()()();
472
+ i0.ɵɵelementEnd();
473
+ i0.ɵɵelementStart(11, "span", 111);
474
+ i0.ɵɵtext(12, "Pass Rate");
475
+ i0.ɵɵelementEnd()();
476
+ i0.ɵɵelement(13, "div", 112);
477
+ i0.ɵɵelementStart(14, "div", 109)(15, "span", 110);
478
+ i0.ɵɵtext(16);
479
+ i0.ɵɵelementEnd();
480
+ i0.ɵɵelementStart(17, "span", 111);
481
+ i0.ɵɵtext(18, "Tests Passed");
482
+ i0.ɵɵelementEnd()()()()();
483
+ i0.ɵɵtemplate(19, TestSuiteRunFormComponentExtended_div_118_div_19_Template, 5, 3, "div", 113)(20, TestSuiteRunFormComponentExtended_div_118_div_20_Template, 10, 3, "div", 114)(21, TestSuiteRunFormComponentExtended_div_118_div_21_Template, 8, 0, "div", 115);
484
+ i0.ɵɵelementEnd();
77
485
  } if (rf & 2) {
78
486
  const ctx_r1 = i0.ɵɵnextContext();
79
487
  i0.ɵɵadvance();
80
- i0.ɵɵclassProp("passed", ctx_r1.record.Status === "Completed" && ctx_r1.getPassRate() >= 90)("failed", ctx_r1.record.Status === "Failed");
488
+ i0.ɵɵclassProp("passed", ctx_r1.record.Status === "Completed" && ctx_r1.getPassRate() >= 90)("failed", ctx_r1.record.Status === "Failed" || ctx_r1.getPassRate() < 50)("running", ctx_r1.record.Status === "Running")("pending", ctx_r1.record.Status === "Pending");
81
489
  i0.ɵɵadvance(2);
82
490
  i0.ɵɵproperty("ngClass", ctx_r1.getStatusIcon());
83
491
  i0.ɵɵadvance(3);
84
- i0.ɵɵtextInterpolate1("SUITE ", ctx_r1.record.Status.toUpperCase(), "");
492
+ i0.ɵɵtextInterpolate1("SUITE ", ctx_r1.record.Status.toUpperCase() || "UNKNOWN", "");
493
+ i0.ɵɵadvance(4);
494
+ i0.ɵɵtextInterpolate1("", ctx_r1.getPassRate().toFixed(1), "%");
495
+ i0.ɵɵadvance(6);
496
+ i0.ɵɵtextInterpolate2("", ctx_r1.record.PassedTests || 0, " / ", ctx_r1.record.TotalTests || 0, "");
497
+ i0.ɵɵadvance(3);
498
+ i0.ɵɵproperty("ngIf", ctx_r1.evaluationMetrics && ctx_r1.feedbacksLoaded);
499
+ i0.ɵɵadvance();
500
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showHuman && ctx_r1.needsReviewItems.length > 0 && ctx_r1.feedbacksLoaded);
501
+ i0.ɵɵadvance();
502
+ i0.ɵɵproperty("ngIf", ctx_r1.record.Status === "Running" || ctx_r1.record.Status === "Pending");
503
+ } }
504
+ function TestSuiteRunFormComponentExtended_div_119_div_1_button_4_Template(rf, ctx) { if (rf & 1) {
505
+ const _r13 = i0.ɵɵgetCurrentView();
506
+ i0.ɵɵelementStart(0, "button", 179);
507
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_1_button_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter("Passed")); });
508
+ i0.ɵɵelement(1, "i", 180);
509
+ i0.ɵɵtext(2);
510
+ i0.ɵɵelementEnd();
511
+ } if (rf & 2) {
512
+ const ctx_r1 = i0.ɵɵnextContext(3);
513
+ i0.ɵɵclassProp("active", ctx_r1.runStatusFilter === "Passed");
514
+ i0.ɵɵadvance(2);
515
+ i0.ɵɵtextInterpolate1(" Passed (", ctx_r1.getRunCountByStatus("Passed"), ") ");
516
+ } }
517
+ function TestSuiteRunFormComponentExtended_div_119_div_1_button_5_Template(rf, ctx) { if (rf & 1) {
518
+ const _r14 = i0.ɵɵgetCurrentView();
519
+ i0.ɵɵelementStart(0, "button", 181);
520
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_1_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter("Failed")); });
521
+ i0.ɵɵelement(1, "i", 100);
522
+ i0.ɵɵtext(2);
523
+ i0.ɵɵelementEnd();
524
+ } if (rf & 2) {
525
+ const ctx_r1 = i0.ɵɵnextContext(3);
526
+ i0.ɵɵclassProp("active", ctx_r1.runStatusFilter === "Failed");
527
+ i0.ɵɵadvance(2);
528
+ i0.ɵɵtextInterpolate1(" Failed (", ctx_r1.getRunCountByStatus("Failed"), ") ");
529
+ } }
530
+ function TestSuiteRunFormComponentExtended_div_119_div_1_button_6_Template(rf, ctx) { if (rf & 1) {
531
+ const _r15 = i0.ɵɵgetCurrentView();
532
+ i0.ɵɵelementStart(0, "button", 182);
533
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_1_button_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter("Error")); });
534
+ i0.ɵɵelement(1, "i", 183);
535
+ i0.ɵɵtext(2);
536
+ i0.ɵɵelementEnd();
537
+ } if (rf & 2) {
538
+ const ctx_r1 = i0.ɵɵnextContext(3);
539
+ i0.ɵɵclassProp("active", ctx_r1.runStatusFilter === "Error");
540
+ i0.ɵɵadvance(2);
541
+ i0.ɵɵtextInterpolate1(" Error (", ctx_r1.getRunCountByStatus("Error"), ") ");
542
+ } }
543
+ function TestSuiteRunFormComponentExtended_div_119_div_1_Template(rf, ctx) { if (rf & 1) {
544
+ const _r12 = i0.ɵɵgetCurrentView();
545
+ i0.ɵɵelementStart(0, "div", 170)(1, "div", 171)(2, "button", 172);
546
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_1_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter(null)); });
547
+ i0.ɵɵtext(3);
548
+ i0.ɵɵelementEnd();
549
+ i0.ɵɵtemplate(4, TestSuiteRunFormComponentExtended_div_119_div_1_button_4_Template, 3, 3, "button", 173)(5, TestSuiteRunFormComponentExtended_div_119_div_1_button_5_Template, 3, 3, "button", 174)(6, TestSuiteRunFormComponentExtended_div_119_div_1_button_6_Template, 3, 3, "button", 175);
550
+ i0.ɵɵelementEnd();
551
+ i0.ɵɵelementStart(7, "div", 176)(8, "button", 177);
552
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_1_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.exportToCSV()); });
553
+ i0.ɵɵelement(9, "i", 178);
554
+ i0.ɵɵtext(10, " Export CSV ");
555
+ i0.ɵɵelementEnd()()();
556
+ } if (rf & 2) {
557
+ const ctx_r1 = i0.ɵɵnextContext(2);
558
+ i0.ɵɵadvance(2);
559
+ i0.ɵɵclassProp("active", ctx_r1.runStatusFilter === null);
560
+ i0.ɵɵadvance();
561
+ i0.ɵɵtextInterpolate1(" All (", ctx_r1.testRuns.length, ") ");
562
+ i0.ɵɵadvance();
563
+ i0.ɵɵproperty("ngIf", ctx_r1.getRunCountByStatus("Passed") > 0);
564
+ i0.ɵɵadvance();
565
+ i0.ɵɵproperty("ngIf", ctx_r1.getRunCountByStatus("Failed") > 0);
566
+ i0.ɵɵadvance();
567
+ i0.ɵɵproperty("ngIf", ctx_r1.getRunCountByStatus("Error") > 0);
568
+ } }
569
+ function TestSuiteRunFormComponentExtended_div_119_div_2_div_2_Template(rf, ctx) { if (rf & 1) {
570
+ i0.ɵɵelementStart(0, "div", 187);
571
+ i0.ɵɵelement(1, "div", 188)(2, "div", 189);
572
+ i0.ɵɵelementStart(3, "div", 190);
573
+ i0.ɵɵelement(4, "div", 191)(5, "div", 192);
574
+ i0.ɵɵelementEnd()();
575
+ } }
576
+ function TestSuiteRunFormComponentExtended_div_119_div_2_Template(rf, ctx) { if (rf & 1) {
577
+ i0.ɵɵelementStart(0, "div", 184)(1, "div", 185);
578
+ i0.ɵɵtemplate(2, TestSuiteRunFormComponentExtended_div_119_div_2_div_2_Template, 6, 0, "div", 186);
579
+ i0.ɵɵelementEnd()();
580
+ } if (rf & 2) {
581
+ i0.ɵɵadvance(2);
582
+ i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c0));
583
+ } }
584
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_span_12_Template(rf, ctx) { if (rf & 1) {
585
+ i0.ɵɵelementStart(0, "span", 211);
586
+ i0.ɵɵelement(1, "i", 18);
587
+ i0.ɵɵtext(2);
588
+ i0.ɵɵelementEnd();
589
+ } if (rf & 2) {
590
+ const run_r17 = i0.ɵɵnextContext().$implicit;
591
+ i0.ɵɵadvance(2);
592
+ i0.ɵɵtextInterpolate1(" ", run_r17.DurationSeconds.toFixed(1), "s ");
593
+ } }
594
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_span_13_Template(rf, ctx) { if (rf & 1) {
595
+ i0.ɵɵelementStart(0, "span", 212);
596
+ i0.ɵɵelement(1, "i", 23);
597
+ i0.ɵɵtext(2);
598
+ i0.ɵɵelementEnd();
599
+ } if (rf & 2) {
600
+ const run_r17 = i0.ɵɵnextContext().$implicit;
601
+ i0.ɵɵadvance(2);
602
+ i0.ɵɵtextInterpolate1(" ", run_r17.CostUSD.toFixed(6), " ");
603
+ } }
604
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_mj_entity_link_pill_14_Template(rf, ctx) { if (rf & 1) {
605
+ i0.ɵɵelement(0, "mj-entity-link-pill", 213);
606
+ } if (rf & 2) {
607
+ const run_r17 = i0.ɵɵnextContext().$implicit;
608
+ i0.ɵɵproperty("entityName", run_r17.TargetLogEntity)("recordId", run_r17.TargetLogID);
609
+ } }
610
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_15_span_1_Template(rf, ctx) { if (rf & 1) {
611
+ i0.ɵɵelementStart(0, "span", 216);
612
+ i0.ɵɵtext(1);
613
+ i0.ɵɵelementEnd();
614
+ } if (rf & 2) {
615
+ const tag_r18 = ctx.$implicit;
616
+ i0.ɵɵadvance();
617
+ i0.ɵɵtextInterpolate(tag_r18);
618
+ } }
619
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_15_Template(rf, ctx) { if (rf & 1) {
620
+ i0.ɵɵelementStart(0, "div", 214);
621
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_15_span_1_Template, 2, 1, "span", 215);
622
+ i0.ɵɵelementEnd();
623
+ } if (rf & 2) {
624
+ const run_r17 = i0.ɵɵnextContext().$implicit;
625
+ const ctx_r1 = i0.ɵɵnextContext(3);
626
+ i0.ɵɵadvance();
627
+ i0.ɵɵproperty("ngForOf", ctx_r1.getRunTags(run_r17));
628
+ } }
629
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_button_7_Template(rf, ctx) { if (rf & 1) {
630
+ const _r20 = i0.ɵɵgetCurrentView();
631
+ i0.ɵɵelementStart(0, "button", 234);
632
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_button_7_Template_button_click_0_listener($event) { const num_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); ctx_r1.setInlineRating(num_r21); return i0.ɵɵresetView($event.stopPropagation()); })("mouseenter", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_button_7_Template_button_mouseenter_0_listener() { const num_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.inlineHoverRating = num_r21); })("mouseleave", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_button_7_Template_button_mouseleave_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.inlineHoverRating = 0); });
633
+ i0.ɵɵtext(1);
634
+ i0.ɵɵelementEnd();
635
+ } if (rf & 2) {
636
+ const num_r21 = ctx.$implicit;
637
+ const ctx_r1 = i0.ɵɵnextContext(5);
638
+ i0.ɵɵclassProp("selected", num_r21 === ctx_r1.inlineRating)("hover", num_r21 === ctx_r1.inlineHoverRating)("low", num_r21 <= 3)("mid", num_r21 >= 4 && num_r21 <= 6)("high", num_r21 >= 7);
639
+ i0.ɵɵadvance();
640
+ i0.ɵɵtextInterpolate1(" ", num_r21, " ");
641
+ } }
642
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_div_8_Template(rf, ctx) { if (rf & 1) {
643
+ i0.ɵɵelementStart(0, "div", 235)(1, "span", 236);
644
+ i0.ɵɵtext(2);
645
+ i0.ɵɵelementEnd();
646
+ i0.ɵɵelementStart(3, "span", 237);
647
+ i0.ɵɵtext(4);
648
+ i0.ɵɵelementEnd()();
649
+ } if (rf & 2) {
650
+ const ctx_r1 = i0.ɵɵnextContext(5);
651
+ i0.ɵɵadvance(2);
652
+ i0.ɵɵtextInterpolate1("", ctx_r1.inlineRating, "/10");
653
+ i0.ɵɵadvance(2);
654
+ i0.ɵɵtextInterpolate(ctx_r1.getInlineRatingLabel());
655
+ } }
656
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template(rf, ctx) { if (rf & 1) {
657
+ const _r19 = i0.ɵɵgetCurrentView();
658
+ i0.ɵɵelementStart(0, "div", 217);
659
+ i0.ɵɵelement(1, "div", 218);
660
+ i0.ɵɵelementStart(2, "div", 219)(3, "div", 220);
661
+ i0.ɵɵtext(4, "Quick Feedback");
662
+ i0.ɵɵelementEnd();
663
+ i0.ɵɵelementStart(5, "div", 221)(6, "div", 222);
664
+ i0.ɵɵtemplate(7, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_button_7_Template, 2, 11, "button", 223);
665
+ i0.ɵɵelementEnd();
666
+ i0.ɵɵtemplate(8, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_div_8_Template, 5, 2, "div", 224);
667
+ i0.ɵɵelementEnd();
668
+ i0.ɵɵelementStart(9, "div", 225)(10, "span", 226);
669
+ i0.ɵɵtext(11, "Was it correct?");
670
+ i0.ɵɵelementEnd();
671
+ i0.ɵɵelementStart(12, "div", 227)(13, "label", 228);
672
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_label_click_13_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
673
+ i0.ɵɵelementStart(14, "input", 229);
674
+ i0.ɵɵtwoWayListener("ngModelChange", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_input_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineIsCorrect, $event) || (ctx_r1.inlineIsCorrect = $event); return i0.ɵɵresetView($event); });
675
+ i0.ɵɵelementEnd();
676
+ i0.ɵɵelementStart(15, "span");
677
+ i0.ɵɵtext(16, "Yes");
678
+ i0.ɵɵelementEnd()();
679
+ i0.ɵɵelementStart(17, "label", 228);
680
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_label_click_17_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
681
+ i0.ɵɵelementStart(18, "input", 229);
682
+ i0.ɵɵtwoWayListener("ngModelChange", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_input_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineIsCorrect, $event) || (ctx_r1.inlineIsCorrect = $event); return i0.ɵɵresetView($event); });
683
+ i0.ɵɵelementEnd();
684
+ i0.ɵɵelementStart(19, "span");
685
+ i0.ɵɵtext(20, "No");
686
+ i0.ɵɵelementEnd()();
687
+ i0.ɵɵelementStart(21, "label", 228);
688
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_label_click_21_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
689
+ i0.ɵɵelementStart(22, "input", 229);
690
+ i0.ɵɵtwoWayListener("ngModelChange", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_input_ngModelChange_22_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineIsCorrect, $event) || (ctx_r1.inlineIsCorrect = $event); return i0.ɵɵresetView($event); });
691
+ i0.ɵɵelementEnd();
692
+ i0.ɵɵelementStart(23, "span");
693
+ i0.ɵɵtext(24, "Not Sure");
694
+ i0.ɵɵelementEnd()()()();
695
+ i0.ɵɵelementStart(25, "div", 230);
696
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_div_click_25_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
697
+ i0.ɵɵelementStart(26, "textarea", 231);
698
+ i0.ɵɵtwoWayListener("ngModelChange", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_textarea_ngModelChange_26_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineComments, $event) || (ctx_r1.inlineComments = $event); return i0.ɵɵresetView($event); });
699
+ i0.ɵɵelementEnd()();
700
+ i0.ɵɵelementStart(27, "div", 232);
701
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_div_click_27_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
702
+ i0.ɵɵelementStart(28, "button", 177);
703
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_button_click_28_listener() { i0.ɵɵrestoreView(_r19); const run_r17 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openTestRun(run_r17.ID)); });
704
+ i0.ɵɵelement(29, "i", 233);
705
+ i0.ɵɵtext(30, " View Full Details ");
706
+ i0.ɵɵelementEnd();
707
+ i0.ɵɵelementStart(31, "button", 95);
708
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template_button_click_31_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.saveInlineFeedback()); });
709
+ i0.ɵɵelement(32, "i", 6);
710
+ i0.ɵɵtext(33);
711
+ i0.ɵɵelementEnd()()()();
712
+ } if (rf & 2) {
713
+ const run_r17 = i0.ɵɵnextContext().$implicit;
714
+ const ctx_r1 = i0.ɵɵnextContext(3);
715
+ i0.ɵɵadvance(7);
716
+ i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(18, _c1));
717
+ i0.ɵɵadvance();
718
+ i0.ɵɵproperty("ngIf", ctx_r1.inlineRating > 0);
719
+ i0.ɵɵadvance(6);
720
+ i0.ɵɵpropertyInterpolate1("name", "correct-", run_r17.ID, "");
721
+ i0.ɵɵproperty("value", true);
722
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.inlineIsCorrect);
723
+ i0.ɵɵadvance(4);
724
+ i0.ɵɵpropertyInterpolate1("name", "correct-", run_r17.ID, "");
725
+ i0.ɵɵproperty("value", false);
726
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.inlineIsCorrect);
727
+ i0.ɵɵadvance(4);
728
+ i0.ɵɵpropertyInterpolate1("name", "correct-", run_r17.ID, "");
729
+ i0.ɵɵproperty("value", null);
730
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.inlineIsCorrect);
731
+ i0.ɵɵadvance(4);
732
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.inlineComments);
733
+ i0.ɵɵadvance(5);
734
+ i0.ɵɵproperty("disabled", !ctx_r1.canSubmitInlineFeedback() || ctx_r1.savingInlineFeedback);
735
+ i0.ɵɵadvance();
736
+ i0.ɵɵproperty("ngClass", ctx_r1.savingInlineFeedback ? "fa-spinner fa-spin" : "fa-save");
737
+ i0.ɵɵadvance();
738
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.savingInlineFeedback ? "Saving..." : ctx_r1.hasFeedback(run_r17.ID) ? "Update" : "Save", " ");
739
+ } }
740
+ function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_Template(rf, ctx) { if (rf & 1) {
741
+ const _r16 = i0.ɵɵgetCurrentView();
742
+ i0.ɵɵelementStart(0, "div", 195)(1, "div", 196);
743
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_3_div_1_Template_div_click_1_listener() { const run_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleRunExpanded(run_r17.ID)); });
744
+ i0.ɵɵelementStart(2, "div", 197);
745
+ i0.ɵɵtext(3);
746
+ i0.ɵɵelementEnd();
747
+ i0.ɵɵelementStart(4, "div", 198);
748
+ i0.ɵɵelement(5, "i", 6);
749
+ i0.ɵɵelementEnd();
750
+ i0.ɵɵelementStart(6, "div", 199)(7, "div", 200)(8, "div", 201);
751
+ i0.ɵɵtext(9);
752
+ i0.ɵɵelementEnd();
753
+ i0.ɵɵelement(10, "app-evaluation-badge", 202);
754
+ i0.ɵɵelementEnd();
755
+ i0.ɵɵelementStart(11, "div", 203);
756
+ i0.ɵɵtemplate(12, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_span_12_Template, 3, 1, "span", 204)(13, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_span_13_Template, 3, 1, "span", 205)(14, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_mj_entity_link_pill_14_Template, 1, 2, "mj-entity-link-pill", 206);
757
+ i0.ɵɵelementEnd();
758
+ i0.ɵɵtemplate(15, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_15_Template, 2, 1, "div", 207);
759
+ i0.ɵɵelementEnd();
760
+ i0.ɵɵelementStart(16, "div", 208);
761
+ i0.ɵɵelement(17, "i", 209);
762
+ i0.ɵɵelementEnd()();
763
+ i0.ɵɵtemplate(18, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_div_18_Template, 34, 19, "div", 210);
764
+ i0.ɵɵelementEnd();
765
+ } if (rf & 2) {
766
+ const run_r17 = ctx.$implicit;
767
+ const ctx_r1 = i0.ɵɵnextContext(3);
768
+ i0.ɵɵadvance(3);
769
+ i0.ɵɵtextInterpolate(run_r17.Sequence || "-");
770
+ i0.ɵɵadvance();
771
+ i0.ɵɵstyleProp("background-color", ctx_r1.getRunStatusColor(run_r17.Status));
772
+ i0.ɵɵadvance();
773
+ i0.ɵɵproperty("ngClass", ctx_r1.getRunStatusIcon(run_r17.Status));
774
+ i0.ɵɵadvance(4);
775
+ i0.ɵɵtextInterpolate(run_r17.Test);
776
+ i0.ɵɵadvance();
777
+ i0.ɵɵproperty("executionStatus", run_r17.Status)("originalStatus", run_r17.Status)("autoScore", run_r17.Score)("humanRating", ctx_r1.getFeedbackRating(run_r17.ID) || null)("humanIsCorrect", ctx_r1.getHumanIsCorrect(run_r17.ID))("hasHumanFeedback", ctx_r1.hasFeedback(run_r17.ID))("preferences", ctx_r1.evalPreferences)("mode", "compact");
85
778
  i0.ɵɵadvance(2);
86
- i0.ɵɵtextInterpolate1("Pass Rate: ", ctx_r1.getPassRate().toFixed(1), "%");
779
+ i0.ɵɵproperty("ngIf", run_r17.DurationSeconds);
780
+ i0.ɵɵadvance();
781
+ i0.ɵɵproperty("ngIf", run_r17.CostUSD);
782
+ i0.ɵɵadvance();
783
+ i0.ɵɵproperty("ngIf", run_r17.TargetLogEntityID && run_r17.TargetLogID);
784
+ i0.ɵɵadvance();
785
+ i0.ɵɵproperty("ngIf", ctx_r1.getRunTags(run_r17).length > 0);
87
786
  i0.ɵɵadvance(2);
88
- i0.ɵɵtextInterpolate2("", ctx_r1.record.PassedTests, " of ", ctx_r1.record.TotalTests, " tests passed");
787
+ i0.ɵɵclassProp("fa-chevron-down", ctx_r1.expandedRunId !== run_r17.ID)("fa-chevron-up", ctx_r1.expandedRunId === run_r17.ID);
788
+ i0.ɵɵadvance();
789
+ i0.ɵɵproperty("ngIf", ctx_r1.expandedRunId === run_r17.ID);
790
+ } }
791
+ function TestSuiteRunFormComponentExtended_div_119_div_3_Template(rf, ctx) { if (rf & 1) {
792
+ i0.ɵɵelementStart(0, "div", 193);
793
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_119_div_3_div_1_Template, 19, 22, "div", 194);
794
+ i0.ɵɵelementEnd();
795
+ } if (rf & 2) {
796
+ const ctx_r1 = i0.ɵɵnextContext(2);
797
+ i0.ɵɵadvance();
798
+ i0.ɵɵproperty("ngForOf", ctx_r1.getFilteredTestRuns());
799
+ } }
800
+ function TestSuiteRunFormComponentExtended_div_119_div_4_Template(rf, ctx) { if (rf & 1) {
801
+ i0.ɵɵelementStart(0, "div", 238)(1, "div", 239);
802
+ i0.ɵɵelement(2, "i", 240);
803
+ i0.ɵɵelementEnd();
804
+ i0.ɵɵelementStart(3, "h4");
805
+ i0.ɵɵtext(4, "No Test Runs Found");
806
+ i0.ɵɵelementEnd();
807
+ i0.ɵɵelementStart(5, "p");
808
+ i0.ɵɵtext(6, "No test runs have been recorded for this suite execution.");
809
+ i0.ɵɵelementEnd()();
810
+ } }
811
+ function TestSuiteRunFormComponentExtended_div_119_div_5_Template(rf, ctx) { if (rf & 1) {
812
+ const _r22 = i0.ɵɵgetCurrentView();
813
+ i0.ɵɵelementStart(0, "div", 238)(1, "div", 239);
814
+ i0.ɵɵelement(2, "i", 241);
815
+ i0.ɵɵelementEnd();
816
+ i0.ɵɵelementStart(3, "h4");
817
+ i0.ɵɵtext(4, "No Matching Runs");
818
+ i0.ɵɵelementEnd();
819
+ i0.ɵɵelementStart(5, "p");
820
+ i0.ɵɵtext(6, "No test runs match the current filter.");
821
+ i0.ɵɵelementEnd();
822
+ i0.ɵɵelementStart(7, "button", 177);
823
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_119_div_5_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter(null)); });
824
+ i0.ɵɵtext(8, "Clear Filter");
825
+ i0.ɵɵelementEnd()();
826
+ } }
827
+ function TestSuiteRunFormComponentExtended_div_119_Template(rf, ctx) { if (rf & 1) {
828
+ i0.ɵɵelementStart(0, "div", 165);
829
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_119_div_1_Template, 11, 6, "div", 166)(2, TestSuiteRunFormComponentExtended_div_119_div_2_Template, 3, 2, "div", 167)(3, TestSuiteRunFormComponentExtended_div_119_div_3_Template, 2, 1, "div", 168)(4, TestSuiteRunFormComponentExtended_div_119_div_4_Template, 7, 0, "div", 169)(5, TestSuiteRunFormComponentExtended_div_119_div_5_Template, 9, 0, "div", 169);
830
+ i0.ɵɵelementEnd();
831
+ } if (rf & 2) {
832
+ const ctx_r1 = i0.ɵɵnextContext();
833
+ i0.ɵɵadvance();
834
+ i0.ɵɵproperty("ngIf", ctx_r1.testRunsLoaded && ctx_r1.testRuns.length > 0);
835
+ i0.ɵɵadvance();
836
+ i0.ɵɵproperty("ngIf", ctx_r1.loadingTestRuns);
837
+ i0.ɵɵadvance();
838
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingTestRuns && ctx_r1.testRuns.length > 0);
839
+ i0.ɵɵadvance();
840
+ i0.ɵɵproperty("ngIf", ctx_r1.testRunsLoaded && !ctx_r1.loadingTestRuns && ctx_r1.testRuns.length === 0);
841
+ i0.ɵɵadvance();
842
+ i0.ɵɵproperty("ngIf", ctx_r1.testRunsLoaded && !ctx_r1.loadingTestRuns && ctx_r1.testRuns.length > 0 && ctx_r1.getFilteredTestRuns().length === 0);
843
+ } }
844
+ function TestSuiteRunFormComponentExtended_div_120_a_15_Template(rf, ctx) { if (rf & 1) {
845
+ const _r23 = i0.ɵɵgetCurrentView();
846
+ i0.ɵɵelementStart(0, "a", 62);
847
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_120_a_15_Template_a_click_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTestSuite()); });
848
+ i0.ɵɵtext(1);
849
+ i0.ɵɵelementEnd();
850
+ } if (rf & 2) {
851
+ const ctx_r1 = i0.ɵɵnextContext(2);
852
+ i0.ɵɵadvance();
853
+ i0.ɵɵtextInterpolate(ctx_r1.testSuite.Name);
854
+ } }
855
+ function TestSuiteRunFormComponentExtended_div_120_span_16_Template(rf, ctx) { if (rf & 1) {
856
+ i0.ɵɵelementStart(0, "span");
857
+ i0.ɵɵtext(1, "Loading...");
858
+ i0.ɵɵelementEnd();
859
+ } }
860
+ function TestSuiteRunFormComponentExtended_div_120_Template(rf, ctx) { if (rf & 1) {
861
+ i0.ɵɵelementStart(0, "div", 242)(1, "div", 243)(2, "h3");
862
+ i0.ɵɵelement(3, "i", 47);
863
+ i0.ɵɵtext(4, " Run Information");
864
+ i0.ɵɵelementEnd();
865
+ i0.ɵɵelementStart(5, "div", 244)(6, "div", 245)(7, "div", 246);
866
+ i0.ɵɵtext(8, "Run ID");
867
+ i0.ɵɵelementEnd();
868
+ i0.ɵɵelementStart(9, "div", 247);
869
+ i0.ɵɵtext(10);
870
+ i0.ɵɵelementEnd()();
871
+ i0.ɵɵelementStart(11, "div", 245)(12, "div", 246);
872
+ i0.ɵɵtext(13, "Test Suite");
873
+ i0.ɵɵelementEnd();
874
+ i0.ɵɵelementStart(14, "div", 248);
875
+ i0.ɵɵtemplate(15, TestSuiteRunFormComponentExtended_div_120_a_15_Template, 2, 1, "a", 249)(16, TestSuiteRunFormComponentExtended_div_120_span_16_Template, 2, 0, "span", 250);
876
+ i0.ɵɵelementEnd()();
877
+ i0.ɵɵelementStart(17, "div", 245)(18, "div", 246);
878
+ i0.ɵɵtext(19, "Status");
879
+ i0.ɵɵelementEnd();
880
+ i0.ɵɵelementStart(20, "div", 248)(21, "span", 251);
881
+ i0.ɵɵtext(22);
882
+ i0.ɵɵelementEnd()()();
883
+ i0.ɵɵelementStart(23, "div", 245)(24, "div", 246);
884
+ i0.ɵɵtext(25, "Run By");
885
+ i0.ɵɵelementEnd();
886
+ i0.ɵɵelementStart(26, "div", 248);
887
+ i0.ɵɵtext(27);
888
+ i0.ɵɵelementEnd()();
889
+ i0.ɵɵelementStart(28, "div", 245)(29, "div", 246);
890
+ i0.ɵɵtext(30, "Started At");
891
+ i0.ɵɵelementEnd();
892
+ i0.ɵɵelementStart(31, "div", 248);
893
+ i0.ɵɵtext(32);
894
+ i0.ɵɵpipe(33, "date");
895
+ i0.ɵɵelementEnd()();
896
+ i0.ɵɵelementStart(34, "div", 245)(35, "div", 246);
897
+ i0.ɵɵtext(36, "Completed At");
898
+ i0.ɵɵelementEnd();
899
+ i0.ɵɵelementStart(37, "div", 248);
900
+ i0.ɵɵtext(38);
901
+ i0.ɵɵpipe(39, "date");
902
+ i0.ɵɵelementEnd()();
903
+ i0.ɵɵelementStart(40, "div", 245)(41, "div", 246);
904
+ i0.ɵɵtext(42, "Environment");
905
+ i0.ɵɵelementEnd();
906
+ i0.ɵɵelementStart(43, "div", 248);
907
+ i0.ɵɵtext(44);
908
+ i0.ɵɵelementEnd()();
909
+ i0.ɵɵelementStart(45, "div", 245)(46, "div", 246);
910
+ i0.ɵɵtext(47, "Trigger Type");
911
+ i0.ɵɵelementEnd();
912
+ i0.ɵɵelementStart(48, "div", 248);
913
+ i0.ɵɵtext(49);
914
+ i0.ɵɵelementEnd()();
915
+ i0.ɵɵelementStart(50, "div", 245)(51, "div", 246);
916
+ i0.ɵɵtext(52, "Git Commit");
917
+ i0.ɵɵelementEnd();
918
+ i0.ɵɵelementStart(53, "div", 247);
919
+ i0.ɵɵtext(54);
920
+ i0.ɵɵelementEnd()();
921
+ i0.ɵɵelementStart(55, "div", 245)(56, "div", 246);
922
+ i0.ɵɵtext(57, "Agent Version");
923
+ i0.ɵɵelementEnd();
924
+ i0.ɵɵelementStart(58, "div", 248);
925
+ i0.ɵɵtext(59);
926
+ i0.ɵɵelementEnd()()()()();
927
+ } if (rf & 2) {
928
+ const ctx_r1 = i0.ɵɵnextContext();
929
+ i0.ɵɵadvance(10);
930
+ i0.ɵɵtextInterpolate(ctx_r1.record.ID);
931
+ i0.ɵɵadvance(5);
932
+ i0.ɵɵproperty("ngIf", ctx_r1.testSuite);
933
+ i0.ɵɵadvance();
934
+ i0.ɵɵproperty("ngIf", !ctx_r1.testSuite);
935
+ i0.ɵɵadvance(5);
936
+ i0.ɵɵproperty("ngClass", ctx_r1.getStatusClass());
937
+ i0.ɵɵadvance();
938
+ i0.ɵɵtextInterpolate(ctx_r1.record.Status);
939
+ i0.ɵɵadvance(5);
940
+ i0.ɵɵtextInterpolate(ctx_r1.record.RunByUser || "N/A");
941
+ i0.ɵɵadvance(5);
942
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(33, 12, ctx_r1.record.StartedAt, "medium"));
943
+ i0.ɵɵadvance(6);
944
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(39, 15, ctx_r1.record.CompletedAt, "medium"));
945
+ i0.ɵɵadvance(6);
946
+ i0.ɵɵtextInterpolate(ctx_r1.record.Environment || "N/A");
947
+ i0.ɵɵadvance(5);
948
+ i0.ɵɵtextInterpolate(ctx_r1.record.TriggerType || "N/A");
949
+ i0.ɵɵadvance(5);
950
+ i0.ɵɵtextInterpolate(ctx_r1.record.GitCommit || "N/A");
951
+ i0.ɵɵadvance(5);
952
+ i0.ɵɵtextInterpolate(ctx_r1.record.AgentVersion || "N/A");
953
+ } }
954
+ function TestSuiteRunFormComponentExtended_div_121_div_1_Template(rf, ctx) { if (rf & 1) {
955
+ i0.ɵɵelementStart(0, "div", 255);
956
+ i0.ɵɵelement(1, "i", 102);
957
+ i0.ɵɵelementStart(2, "span");
958
+ i0.ɵɵtext(3, "Loading test results...");
959
+ i0.ɵɵelementEnd()();
960
+ } }
961
+ function TestSuiteRunFormComponentExtended_div_121_div_2_Template(rf, ctx) { if (rf & 1) {
962
+ i0.ɵɵelementStart(0, "div", 256)(1, "h3");
963
+ i0.ɵɵelement(2, "i", 257);
964
+ i0.ɵɵtext(3, " Summary Statistics");
965
+ i0.ɵɵelementEnd();
966
+ i0.ɵɵelementStart(4, "div", 258)(5, "div", 259)(6, "div", 260);
967
+ i0.ɵɵelement(7, "i", 28);
968
+ i0.ɵɵelementEnd();
969
+ i0.ɵɵelementStart(8, "div", 261)(9, "div", 110);
970
+ i0.ɵɵtext(10);
971
+ i0.ɵɵelementEnd();
972
+ i0.ɵɵelementStart(11, "div", 111);
973
+ i0.ɵɵtext(12, "Passed");
974
+ i0.ɵɵelementEnd();
975
+ i0.ɵɵelementStart(13, "div", 262);
976
+ i0.ɵɵtext(14);
977
+ i0.ɵɵelementEnd()()();
978
+ i0.ɵɵelementStart(15, "div", 259)(16, "div", 263);
979
+ i0.ɵɵelement(17, "i", 33);
980
+ i0.ɵɵelementEnd();
981
+ i0.ɵɵelementStart(18, "div", 261)(19, "div", 110);
982
+ i0.ɵɵtext(20);
983
+ i0.ɵɵelementEnd();
984
+ i0.ɵɵelementStart(21, "div", 111);
985
+ i0.ɵɵtext(22, "Failed");
986
+ i0.ɵɵelementEnd();
987
+ i0.ɵɵelementStart(23, "div", 262);
988
+ i0.ɵɵtext(24);
989
+ i0.ɵɵelementEnd()()();
990
+ i0.ɵɵelementStart(25, "div", 259)(26, "div", 264);
991
+ i0.ɵɵelement(27, "i", 265);
992
+ i0.ɵɵelementEnd();
993
+ i0.ɵɵelementStart(28, "div", 261)(29, "div", 110);
994
+ i0.ɵɵtext(30);
995
+ i0.ɵɵelementEnd();
996
+ i0.ɵɵelementStart(31, "div", 111);
997
+ i0.ɵɵtext(32, "Avg Score");
998
+ i0.ɵɵelementEnd()()();
999
+ i0.ɵɵelementStart(33, "div", 259)(34, "div", 266);
1000
+ i0.ɵɵelement(35, "i", 18);
1001
+ i0.ɵɵelementEnd();
1002
+ i0.ɵɵelementStart(36, "div", 261)(37, "div", 110);
1003
+ i0.ɵɵtext(38);
1004
+ i0.ɵɵelementEnd();
1005
+ i0.ɵɵelementStart(39, "div", 111);
1006
+ i0.ɵɵtext(40, "Avg Duration");
1007
+ i0.ɵɵelementEnd()()();
1008
+ i0.ɵɵelementStart(41, "div", 259)(42, "div", 267);
1009
+ i0.ɵɵelement(43, "i", 23);
1010
+ i0.ɵɵelementEnd();
1011
+ i0.ɵɵelementStart(44, "div", 261)(45, "div", 110);
1012
+ i0.ɵɵtext(46);
1013
+ i0.ɵɵelementEnd();
1014
+ i0.ɵɵelementStart(47, "div", 111);
1015
+ i0.ɵɵtext(48, "Total Cost");
1016
+ i0.ɵɵelementEnd()()()()();
1017
+ } if (rf & 2) {
1018
+ const ctx_r1 = i0.ɵɵnextContext(2);
1019
+ i0.ɵɵadvance(10);
1020
+ i0.ɵɵtextInterpolate(ctx_r1.getPassedCount());
1021
+ i0.ɵɵadvance(4);
1022
+ i0.ɵɵtextInterpolate1("", ctx_r1.getPassedPercent().toFixed(1), "%");
1023
+ i0.ɵɵadvance(6);
1024
+ i0.ɵɵtextInterpolate(ctx_r1.getFailedCount());
1025
+ i0.ɵɵadvance(4);
1026
+ i0.ɵɵtextInterpolate1("", ctx_r1.getFailedPercent().toFixed(1), "%");
1027
+ i0.ɵɵadvance(6);
1028
+ i0.ɵɵtextInterpolate1("", (ctx_r1.getAverageScore() * 100).toFixed(1), "%");
1029
+ i0.ɵɵadvance(8);
1030
+ i0.ɵɵtextInterpolate1("", ctx_r1.getAverageDuration().toFixed(1), "s");
1031
+ i0.ɵɵadvance(8);
1032
+ i0.ɵɵtextInterpolate1("$", ctx_r1.getTotalCost().toFixed(4), "");
1033
+ } }
1034
+ function TestSuiteRunFormComponentExtended_div_121_div_3_th_26_Template(rf, ctx) { if (rf & 1) {
1035
+ i0.ɵɵelementStart(0, "th", 285);
1036
+ i0.ɵɵtext(1, "Status");
1037
+ i0.ɵɵelementEnd();
1038
+ } }
1039
+ function TestSuiteRunFormComponentExtended_div_121_div_3_th_27_Template(rf, ctx) { if (rf & 1) {
1040
+ i0.ɵɵelementStart(0, "th", 286);
1041
+ i0.ɵɵtext(1, "Auto Score");
1042
+ i0.ɵɵelementEnd();
1043
+ } }
1044
+ function TestSuiteRunFormComponentExtended_div_121_div_3_th_28_Template(rf, ctx) { if (rf & 1) {
1045
+ i0.ɵɵelementStart(0, "th", 287);
1046
+ i0.ɵɵtext(1, "Human Score");
1047
+ i0.ɵɵelementEnd();
1048
+ } }
1049
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_div_7_span_1_Template(rf, ctx) { if (rf & 1) {
1050
+ i0.ɵɵelementStart(0, "span", 295);
1051
+ i0.ɵɵtext(1);
1052
+ i0.ɵɵelementEnd();
1053
+ } if (rf & 2) {
1054
+ const tag_r26 = ctx.$implicit;
1055
+ i0.ɵɵadvance();
1056
+ i0.ɵɵtextInterpolate(tag_r26);
1057
+ } }
1058
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_div_7_Template(rf, ctx) { if (rf & 1) {
1059
+ i0.ɵɵelementStart(0, "div", 293);
1060
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_div_7_span_1_Template, 2, 1, "span", 294);
1061
+ i0.ɵɵelementEnd();
1062
+ } if (rf & 2) {
1063
+ const run_r25 = i0.ɵɵnextContext().$implicit;
1064
+ const ctx_r1 = i0.ɵɵnextContext(3);
1065
+ i0.ɵɵadvance();
1066
+ i0.ɵɵproperty("ngForOf", ctx_r1.getRunTags(run_r25).slice(0, 2));
1067
+ } }
1068
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_8_Template(rf, ctx) { if (rf & 1) {
1069
+ i0.ɵɵelementStart(0, "td", 285)(1, "span", 9);
1070
+ i0.ɵɵelement(2, "i", 209);
1071
+ i0.ɵɵtext(3);
1072
+ i0.ɵɵelementEnd()();
1073
+ } if (rf & 2) {
1074
+ const run_r25 = i0.ɵɵnextContext().$implicit;
1075
+ i0.ɵɵadvance();
1076
+ i0.ɵɵproperty("ngClass", "status-" + run_r25.Status.toLowerCase());
1077
+ i0.ɵɵadvance();
1078
+ i0.ɵɵclassProp("fa-check-circle", run_r25.Status === "Passed")("fa-times-circle", run_r25.Status === "Failed")("fa-exclamation-circle", run_r25.Status === "Error")("fa-forward", run_r25.Status === "Skipped")("fa-clock", run_r25.Status === "Pending")("fa-spinner", run_r25.Status === "Running")("fa-spin", run_r25.Status === "Running");
1079
+ i0.ɵɵadvance();
1080
+ i0.ɵɵtextInterpolate1(" ", run_r25.Status, " ");
1081
+ } }
1082
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_9_div_1_Template(rf, ctx) { if (rf & 1) {
1083
+ i0.ɵɵelementStart(0, "div", 297)(1, "div", 298);
1084
+ i0.ɵɵelement(2, "div", 299);
1085
+ i0.ɵɵelementEnd();
1086
+ i0.ɵɵelementStart(3, "span", 300);
1087
+ i0.ɵɵtext(4);
1088
+ i0.ɵɵelementEnd()();
1089
+ } if (rf & 2) {
1090
+ const run_r25 = i0.ɵɵnextContext(2).$implicit;
1091
+ i0.ɵɵadvance(2);
1092
+ i0.ɵɵstyleProp("width", run_r25.Score * 100, "%");
1093
+ i0.ɵɵclassProp("high", run_r25.Score >= 0.8)("medium", run_r25.Score >= 0.5 && run_r25.Score < 0.8)("low", run_r25.Score < 0.5);
1094
+ i0.ɵɵadvance(2);
1095
+ i0.ɵɵtextInterpolate1("", (run_r25.Score * 100).toFixed(0), "%");
1096
+ } }
1097
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_9_span_2_Template(rf, ctx) { if (rf & 1) {
1098
+ i0.ɵɵelementStart(0, "span", 301);
1099
+ i0.ɵɵtext(1, "\u2014");
1100
+ i0.ɵɵelementEnd();
1101
+ } }
1102
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_9_Template(rf, ctx) { if (rf & 1) {
1103
+ i0.ɵɵelementStart(0, "td", 286);
1104
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_9_div_1_Template, 5, 9, "div", 296)(2, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_9_span_2_Template, 2, 0, "span", 292);
1105
+ i0.ɵɵelementEnd();
1106
+ } if (rf & 2) {
1107
+ const run_r25 = i0.ɵɵnextContext().$implicit;
1108
+ i0.ɵɵadvance();
1109
+ i0.ɵɵproperty("ngIf", run_r25.Score != null);
1110
+ i0.ɵɵadvance();
1111
+ i0.ɵɵproperty("ngIf", run_r25.Score == null);
1112
+ } }
1113
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_div_1_span_3_Template(rf, ctx) { if (rf & 1) {
1114
+ i0.ɵɵelementStart(0, "span", 307);
1115
+ i0.ɵɵelement(1, "i", 209);
1116
+ i0.ɵɵelementEnd();
1117
+ } if (rf & 2) {
1118
+ const run_r25 = i0.ɵɵnextContext(3).$implicit;
1119
+ const ctx_r1 = i0.ɵɵnextContext(3);
1120
+ i0.ɵɵadvance();
1121
+ i0.ɵɵclassProp("fa-check", ctx_r1.getHumanIsCorrect(run_r25.ID) === true)("fa-times", ctx_r1.getHumanIsCorrect(run_r25.ID) === false)("correct", ctx_r1.getHumanIsCorrect(run_r25.ID) === true)("incorrect", ctx_r1.getHumanIsCorrect(run_r25.ID) === false);
1122
+ } }
1123
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_div_1_Template(rf, ctx) { if (rf & 1) {
1124
+ i0.ɵɵelementStart(0, "div", 304)(1, "span", 305);
1125
+ i0.ɵɵtext(2);
1126
+ i0.ɵɵelementEnd();
1127
+ i0.ɵɵtemplate(3, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_div_1_span_3_Template, 2, 8, "span", 306);
1128
+ i0.ɵɵelementEnd();
1129
+ } if (rf & 2) {
1130
+ const run_r25 = i0.ɵɵnextContext(2).$implicit;
1131
+ const ctx_r1 = i0.ɵɵnextContext(3);
1132
+ i0.ɵɵadvance();
1133
+ i0.ɵɵclassProp("low", ctx_r1.getFeedbackRating(run_r25.ID) <= 3)("mid", ctx_r1.getFeedbackRating(run_r25.ID) >= 4 && ctx_r1.getFeedbackRating(run_r25.ID) <= 6)("high", ctx_r1.getFeedbackRating(run_r25.ID) >= 7);
1134
+ i0.ɵɵadvance();
1135
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getFeedbackRating(run_r25.ID), "/10 ");
1136
+ i0.ɵɵadvance();
1137
+ i0.ɵɵproperty("ngIf", ctx_r1.getHumanIsCorrect(run_r25.ID) !== null);
1138
+ } }
1139
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_span_2_Template(rf, ctx) { if (rf & 1) {
1140
+ i0.ɵɵelementStart(0, "span", 308);
1141
+ i0.ɵɵelement(1, "i", 309);
1142
+ i0.ɵɵelementEnd();
1143
+ } }
1144
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_Template(rf, ctx) { if (rf & 1) {
1145
+ i0.ɵɵelementStart(0, "td", 287);
1146
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_div_1_Template, 4, 8, "div", 302)(2, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_span_2_Template, 2, 0, "span", 303);
1147
+ i0.ɵɵelementEnd();
1148
+ } if (rf & 2) {
1149
+ const run_r25 = i0.ɵɵnextContext().$implicit;
1150
+ const ctx_r1 = i0.ɵɵnextContext(3);
1151
+ i0.ɵɵadvance();
1152
+ i0.ɵɵproperty("ngIf", ctx_r1.hasFeedback(run_r25.ID));
1153
+ i0.ɵɵadvance();
1154
+ i0.ɵɵproperty("ngIf", !ctx_r1.hasFeedback(run_r25.ID));
89
1155
  } }
90
- function TestSuiteRunFormComponentExtended_div_95_div_1_div_1_span_11_Template(rf, ctx) { if (rf & 1) {
1156
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_12_Template(rf, ctx) { if (rf & 1) {
91
1157
  i0.ɵɵelementStart(0, "span");
92
1158
  i0.ɵɵtext(1);
93
1159
  i0.ɵɵelementEnd();
94
1160
  } if (rf & 2) {
95
- const run_r4 = i0.ɵɵnextContext().$implicit;
1161
+ const run_r25 = i0.ɵɵnextContext().$implicit;
96
1162
  i0.ɵɵadvance();
97
- i0.ɵɵtextInterpolate1("Score: ", run_r4.Score.toFixed(4), "");
1163
+ i0.ɵɵtextInterpolate1("", run_r25.DurationSeconds.toFixed(1), "s");
98
1164
  } }
99
- function TestSuiteRunFormComponentExtended_div_95_div_1_div_1_span_12_Template(rf, ctx) { if (rf & 1) {
1165
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_13_Template(rf, ctx) { if (rf & 1) {
1166
+ i0.ɵɵelementStart(0, "span", 301);
1167
+ i0.ɵɵtext(1, "\u2014");
1168
+ i0.ɵɵelementEnd();
1169
+ } }
1170
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_15_Template(rf, ctx) { if (rf & 1) {
100
1171
  i0.ɵɵelementStart(0, "span");
101
1172
  i0.ɵɵtext(1);
102
1173
  i0.ɵɵelementEnd();
103
1174
  } if (rf & 2) {
104
- const run_r4 = i0.ɵɵnextContext().$implicit;
1175
+ const run_r25 = i0.ɵɵnextContext().$implicit;
105
1176
  i0.ɵɵadvance();
106
- i0.ɵɵtextInterpolate1("", run_r4.DurationSeconds.toFixed(1), "s");
1177
+ i0.ɵɵtextInterpolate1("$", run_r25.CostUSD.toFixed(4), "");
107
1178
  } }
108
- function TestSuiteRunFormComponentExtended_div_95_div_1_div_1_Template(rf, ctx) { if (rf & 1) {
109
- const _r3 = i0.ɵɵgetCurrentView();
110
- i0.ɵɵelementStart(0, "div", 60);
111
- i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_95_div_1_div_1_Template_div_click_0_listener() { const run_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openTestRun(run_r4.ID)); });
112
- i0.ɵɵelementStart(1, "div", 61);
113
- i0.ɵɵtext(2);
1179
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_16_Template(rf, ctx) { if (rf & 1) {
1180
+ i0.ɵɵelementStart(0, "span", 301);
1181
+ i0.ɵɵtext(1, "\u2014");
114
1182
  i0.ɵɵelementEnd();
115
- i0.ɵɵelementStart(3, "div", 62);
116
- i0.ɵɵelement(4, "i", 63);
117
- i0.ɵɵelementEnd();
118
- i0.ɵɵelementStart(5, "div", 64)(6, "div", 65);
119
- i0.ɵɵtext(7);
1183
+ } }
1184
+ function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_Template(rf, ctx) { if (rf & 1) {
1185
+ const _r24 = i0.ɵɵgetCurrentView();
1186
+ i0.ɵɵelementStart(0, "tr", 288);
1187
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_Template_tr_click_0_listener() { const run_r25 = i0.ɵɵrestoreView(_r24).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openTestRun(run_r25.ID)); });
1188
+ i0.ɵɵelementStart(1, "td", 277);
1189
+ i0.ɵɵtext(2);
120
1190
  i0.ɵɵelementEnd();
121
- i0.ɵɵelementStart(8, "div", 66)(9, "span", 67);
122
- i0.ɵɵtext(10);
1191
+ i0.ɵɵelementStart(3, "td", 278)(4, "div", 289)(5, "span", 290);
1192
+ i0.ɵɵtext(6);
123
1193
  i0.ɵɵelementEnd();
124
- i0.ɵɵtemplate(11, TestSuiteRunFormComponentExtended_div_95_div_1_div_1_span_11_Template, 2, 1, "span", 68)(12, TestSuiteRunFormComponentExtended_div_95_div_1_div_1_span_12_Template, 2, 1, "span", 68);
1194
+ i0.ɵɵtemplate(7, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_div_7_Template, 2, 1, "div", 291);
125
1195
  i0.ɵɵelementEnd()();
126
- i0.ɵɵelement(13, "i", 45);
1196
+ i0.ɵɵtemplate(8, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_8_Template, 4, 16, "td", 279)(9, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_9_Template, 3, 2, "td", 280)(10, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_td_10_Template, 3, 2, "td", 281);
1197
+ i0.ɵɵelementStart(11, "td", 282);
1198
+ i0.ɵɵtemplate(12, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_12_Template, 2, 1, "span", 250)(13, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_13_Template, 2, 0, "span", 292);
127
1199
  i0.ɵɵelementEnd();
1200
+ i0.ɵɵelementStart(14, "td", 283);
1201
+ i0.ɵɵtemplate(15, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_15_Template, 2, 1, "span", 250)(16, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_span_16_Template, 2, 0, "span", 292);
1202
+ i0.ɵɵelementEnd()();
128
1203
  } if (rf & 2) {
129
- const run_r4 = ctx.$implicit;
1204
+ const run_r25 = ctx.$implicit;
1205
+ const i_r27 = ctx.index;
1206
+ const ctx_r1 = i0.ɵɵnextContext(3);
1207
+ i0.ɵɵclassProp("row-passed", run_r25.Status === "Passed")("row-failed", run_r25.Status === "Failed")("row-error", run_r25.Status === "Error")("row-skipped", run_r25.Status === "Skipped");
130
1208
  i0.ɵɵadvance(2);
131
- i0.ɵɵtextInterpolate(run_r4.Sequence);
1209
+ i0.ɵɵtextInterpolate(i_r27 + 1);
1210
+ i0.ɵɵadvance(4);
1211
+ i0.ɵɵtextInterpolate(run_r25.Test || "Unknown Test");
132
1212
  i0.ɵɵadvance();
133
- i0.ɵɵstyleProp("background-color", run_r4.Status === "Passed" ? "#4caf50" : run_r4.Status === "Failed" ? "#f44336" : "#ff9800");
1213
+ i0.ɵɵproperty("ngIf", ctx_r1.getRunTags(run_r25).length > 0);
134
1214
  i0.ɵɵadvance();
135
- i0.ɵɵclassProp("fa-check", run_r4.Status === "Passed")("fa-times", run_r4.Status === "Failed")("fa-exclamation", run_r4.Status === "Error");
136
- i0.ɵɵadvance(3);
137
- i0.ɵɵtextInterpolate(run_r4.Test);
138
- i0.ɵɵadvance(2);
139
- i0.ɵɵstyleProp("color", run_r4.Status === "Passed" ? "#4caf50" : run_r4.Status === "Failed" ? "#f44336" : "#ff9800");
1215
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showExecution);
1216
+ i0.ɵɵadvance();
1217
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showAuto);
140
1218
  i0.ɵɵadvance();
141
- i0.ɵɵtextInterpolate(run_r4.Status);
1219
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showHuman);
1220
+ i0.ɵɵadvance(2);
1221
+ i0.ɵɵproperty("ngIf", run_r25.DurationSeconds);
142
1222
  i0.ɵɵadvance();
143
- i0.ɵɵproperty("ngIf", run_r4.Score != null);
1223
+ i0.ɵɵproperty("ngIf", !run_r25.DurationSeconds);
1224
+ i0.ɵɵadvance(2);
1225
+ i0.ɵɵproperty("ngIf", run_r25.CostUSD);
144
1226
  i0.ɵɵadvance();
145
- i0.ɵɵproperty("ngIf", run_r4.DurationSeconds);
1227
+ i0.ɵɵproperty("ngIf", !run_r25.CostUSD);
146
1228
  } }
147
- function TestSuiteRunFormComponentExtended_div_95_div_1_Template(rf, ctx) { if (rf & 1) {
148
- i0.ɵɵelementStart(0, "div", 58);
149
- i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_95_div_1_div_1_Template, 14, 15, "div", 59);
1229
+ function TestSuiteRunFormComponentExtended_div_121_div_3_Template(rf, ctx) { if (rf & 1) {
1230
+ i0.ɵɵelementStart(0, "div", 256)(1, "div", 268)(2, "h3");
1231
+ i0.ɵɵelement(3, "i", 269);
1232
+ i0.ɵɵtext(4, " Test Results");
150
1233
  i0.ɵɵelementEnd();
1234
+ i0.ɵɵelementStart(5, "div", 270)(6, "span", 271);
1235
+ i0.ɵɵelement(7, "i", 28);
1236
+ i0.ɵɵtext(8, " Passed");
1237
+ i0.ɵɵelementEnd();
1238
+ i0.ɵɵelementStart(9, "span", 272);
1239
+ i0.ɵɵelement(10, "i", 33);
1240
+ i0.ɵɵtext(11, " Failed");
1241
+ i0.ɵɵelementEnd();
1242
+ i0.ɵɵelementStart(12, "span", 273);
1243
+ i0.ɵɵelement(13, "i", 35);
1244
+ i0.ɵɵtext(14, " Error");
1245
+ i0.ɵɵelementEnd();
1246
+ i0.ɵɵelementStart(15, "span", 274);
1247
+ i0.ɵɵelement(16, "i", 37);
1248
+ i0.ɵɵtext(17, " Skipped");
1249
+ i0.ɵɵelementEnd()()();
1250
+ i0.ɵɵelementStart(18, "div", 275)(19, "table", 276)(20, "thead")(21, "tr")(22, "th", 277);
1251
+ i0.ɵɵtext(23, "#");
1252
+ i0.ɵɵelementEnd();
1253
+ i0.ɵɵelementStart(24, "th", 278);
1254
+ i0.ɵɵtext(25, "Test Name");
1255
+ i0.ɵɵelementEnd();
1256
+ i0.ɵɵtemplate(26, TestSuiteRunFormComponentExtended_div_121_div_3_th_26_Template, 2, 0, "th", 279)(27, TestSuiteRunFormComponentExtended_div_121_div_3_th_27_Template, 2, 0, "th", 280)(28, TestSuiteRunFormComponentExtended_div_121_div_3_th_28_Template, 2, 0, "th", 281);
1257
+ i0.ɵɵelementStart(29, "th", 282);
1258
+ i0.ɵɵtext(30, "Duration");
1259
+ i0.ɵɵelementEnd();
1260
+ i0.ɵɵelementStart(31, "th", 283);
1261
+ i0.ɵɵtext(32, "Cost");
1262
+ i0.ɵɵelementEnd()()();
1263
+ i0.ɵɵelementStart(33, "tbody");
1264
+ i0.ɵɵtemplate(34, TestSuiteRunFormComponentExtended_div_121_div_3_tr_34_Template, 17, 18, "tr", 284);
1265
+ i0.ɵɵelementEnd()()()();
151
1266
  } if (rf & 2) {
152
1267
  const ctx_r1 = i0.ɵɵnextContext(2);
1268
+ i0.ɵɵadvance(26);
1269
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showExecution);
1270
+ i0.ɵɵadvance();
1271
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showAuto);
153
1272
  i0.ɵɵadvance();
1273
+ i0.ɵɵproperty("ngIf", ctx_r1.evalPreferences.showHuman);
1274
+ i0.ɵɵadvance(6);
154
1275
  i0.ɵɵproperty("ngForOf", ctx_r1.testRuns);
155
1276
  } }
156
- function TestSuiteRunFormComponentExtended_div_95_div_2_Template(rf, ctx) { if (rf & 1) {
157
- i0.ɵɵelementStart(0, "div", 69);
158
- i0.ɵɵelement(1, "i", 70);
159
- i0.ɵɵelementStart(2, "p");
160
- i0.ɵɵtext(3, "No test runs found for this suite execution");
1277
+ function TestSuiteRunFormComponentExtended_div_121_div_4_Template(rf, ctx) { if (rf & 1) {
1278
+ i0.ɵɵelementStart(0, "div", 238)(1, "div", 239);
1279
+ i0.ɵɵelement(2, "i", 49);
1280
+ i0.ɵɵelementEnd();
1281
+ i0.ɵɵelementStart(3, "h4");
1282
+ i0.ɵɵtext(4, "No Test Results Yet");
1283
+ i0.ɵɵelementEnd();
1284
+ i0.ɵɵelementStart(5, "p");
1285
+ i0.ɵɵtext(6, "Test runs will appear here once the suite execution completes.");
161
1286
  i0.ɵɵelementEnd()();
162
1287
  } }
163
- function TestSuiteRunFormComponentExtended_div_95_Template(rf, ctx) { if (rf & 1) {
164
- i0.ɵɵelementStart(0, "div", 55);
165
- i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_95_div_1_Template, 2, 1, "div", 56)(2, TestSuiteRunFormComponentExtended_div_95_div_2_Template, 4, 0, "div", 57);
1288
+ function TestSuiteRunFormComponentExtended_div_121_Template(rf, ctx) { if (rf & 1) {
1289
+ i0.ɵɵelementStart(0, "div", 252);
1290
+ i0.ɵɵtemplate(1, TestSuiteRunFormComponentExtended_div_121_div_1_Template, 4, 0, "div", 253)(2, TestSuiteRunFormComponentExtended_div_121_div_2_Template, 49, 7, "div", 254)(3, TestSuiteRunFormComponentExtended_div_121_div_3_Template, 35, 4, "div", 254)(4, TestSuiteRunFormComponentExtended_div_121_div_4_Template, 7, 0, "div", 169);
166
1291
  i0.ɵɵelementEnd();
167
1292
  } if (rf & 2) {
168
1293
  const ctx_r1 = i0.ɵɵnextContext();
169
1294
  i0.ɵɵadvance();
170
- i0.ɵɵproperty("ngIf", ctx_r1.testRuns.length > 0);
1295
+ i0.ɵɵproperty("ngIf", ctx_r1.loadingTestRuns);
1296
+ i0.ɵɵadvance();
1297
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingTestRuns && ctx_r1.testRuns.length > 0);
171
1298
  i0.ɵɵadvance();
172
- i0.ɵɵproperty("ngIf", ctx_r1.testRunsLoaded && ctx_r1.testRuns.length === 0);
1299
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingTestRuns && ctx_r1.testRuns.length > 0);
1300
+ i0.ɵɵadvance();
1301
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingTestRuns && ctx_r1.testRunsLoaded && ctx_r1.testRuns.length === 0);
173
1302
  } }
174
- function TestSuiteRunFormComponentExtended_div_96_a_11_Template(rf, ctx) { if (rf & 1) {
175
- const _r5 = i0.ɵɵgetCurrentView();
176
- i0.ɵɵelementStart(0, "a", 43);
177
- i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_96_a_11_Template_a_click_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTestSuite()); });
178
- i0.ɵɵtext(1);
1303
+ function TestSuiteRunFormComponentExtended_div_122_Template(rf, ctx) { if (rf & 1) {
1304
+ i0.ɵɵelementStart(0, "div", 310);
1305
+ i0.ɵɵelement(1, "mj-execution-context", 311);
179
1306
  i0.ɵɵelementEnd();
180
1307
  } if (rf & 2) {
181
- const ctx_r1 = i0.ɵɵnextContext(2);
1308
+ const ctx_r1 = i0.ɵɵnextContext();
182
1309
  i0.ɵɵadvance();
183
- i0.ɵɵtextInterpolate(ctx_r1.testSuite.Name);
1310
+ 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);
184
1311
  } }
185
- function TestSuiteRunFormComponentExtended_div_96_Template(rf, ctx) { if (rf & 1) {
186
- i0.ɵɵelementStart(0, "div", 71)(1, "div", 72)(2, "div", 73)(3, "div", 74);
187
- i0.ɵɵtext(4, "Run ID");
188
- i0.ɵɵelementEnd();
189
- i0.ɵɵelementStart(5, "div", 75);
190
- i0.ɵɵtext(6);
1312
+ function TestSuiteRunFormComponentExtended_div_125_Template(rf, ctx) { if (rf & 1) {
1313
+ const _r28 = i0.ɵɵgetCurrentView();
1314
+ i0.ɵɵelementStart(0, "div", 312)(1, "div", 313);
1315
+ i0.ɵɵelement(2, "i", 59);
1316
+ i0.ɵɵtext(3, " Shortcuts ");
1317
+ i0.ɵɵelementStart(4, "button", 314);
1318
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_div_125_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r28); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleShortcuts()); });
1319
+ i0.ɵɵelement(5, "i", 100);
191
1320
  i0.ɵɵelementEnd()();
192
- i0.ɵɵelementStart(7, "div", 73)(8, "div", 74);
193
- i0.ɵɵtext(9, "Test Suite");
1321
+ i0.ɵɵelementStart(6, "div", 315)(7, "div", 316)(8, "span");
1322
+ i0.ɵɵtext(9, "Refresh");
194
1323
  i0.ɵɵelementEnd();
195
- i0.ɵɵelementStart(10, "div", 75);
196
- i0.ɵɵtemplate(11, TestSuiteRunFormComponentExtended_div_96_a_11_Template, 2, 1, "a", 76);
197
- i0.ɵɵelementEnd()();
198
- i0.ɵɵelementStart(12, "div", 73)(13, "div", 74);
199
- i0.ɵɵtext(14, "Status");
1324
+ i0.ɵɵelementStart(10, "span", 317)(11, "kbd");
1325
+ i0.ɵɵtext(12, "Cmd");
200
1326
  i0.ɵɵelementEnd();
201
- i0.ɵɵelementStart(15, "div", 75);
202
- i0.ɵɵtext(16);
203
- i0.ɵɵelementEnd()();
204
- i0.ɵɵelementStart(17, "div", 73)(18, "div", 74);
205
- i0.ɵɵtext(19, "Run By");
1327
+ i0.ɵɵelementStart(13, "kbd");
1328
+ i0.ɵɵtext(14, "R");
1329
+ i0.ɵɵelementEnd()()();
1330
+ i0.ɵɵelementStart(15, "div", 316)(16, "span");
1331
+ i0.ɵɵtext(17, "Re-run Suite");
206
1332
  i0.ɵɵelementEnd();
207
- i0.ɵɵelementStart(20, "div", 75);
208
- i0.ɵɵtext(21);
209
- i0.ɵɵelementEnd()();
210
- i0.ɵɵelementStart(22, "div", 73)(23, "div", 74);
211
- i0.ɵɵtext(24, "Environment");
1333
+ i0.ɵɵelementStart(18, "span", 317)(19, "kbd");
1334
+ i0.ɵɵtext(20, "Cmd");
212
1335
  i0.ɵɵelementEnd();
213
- i0.ɵɵelementStart(25, "div", 75);
214
- i0.ɵɵtext(26);
215
- i0.ɵɵelementEnd()();
216
- i0.ɵɵelementStart(27, "div", 73)(28, "div", 74);
217
- i0.ɵɵtext(29, "Trigger Type");
1336
+ i0.ɵɵelementStart(21, "kbd");
1337
+ i0.ɵɵtext(22, "Shift");
218
1338
  i0.ɵɵelementEnd();
219
- i0.ɵɵelementStart(30, "div", 75);
220
- i0.ɵɵtext(31);
221
- i0.ɵɵelementEnd()();
222
- i0.ɵɵelementStart(32, "div", 73)(33, "div", 74);
223
- i0.ɵɵtext(34, "Git Commit");
1339
+ i0.ɵɵelementStart(23, "kbd");
1340
+ i0.ɵɵtext(24, "R");
1341
+ i0.ɵɵelementEnd()()();
1342
+ i0.ɵɵelementStart(25, "div", 316)(26, "span");
1343
+ i0.ɵɵtext(27, "Switch Tabs");
224
1344
  i0.ɵɵelementEnd();
225
- i0.ɵɵelementStart(35, "div", 75);
226
- i0.ɵɵtext(36);
227
- i0.ɵɵelementEnd()();
228
- i0.ɵɵelementStart(37, "div", 73)(38, "div", 74);
229
- i0.ɵɵtext(39, "Agent Version");
1345
+ i0.ɵɵelementStart(28, "span", 317)(29, "kbd");
1346
+ i0.ɵɵtext(30, "1");
230
1347
  i0.ɵɵelementEnd();
231
- i0.ɵɵelementStart(40, "div", 75);
232
- i0.ɵɵtext(41);
233
- i0.ɵɵelementEnd()()()();
234
- } if (rf & 2) {
235
- const ctx_r1 = i0.ɵɵnextContext();
236
- i0.ɵɵadvance(6);
237
- i0.ɵɵtextInterpolate(ctx_r1.record.ID);
238
- i0.ɵɵadvance(5);
239
- i0.ɵɵproperty("ngIf", ctx_r1.testSuite);
240
- i0.ɵɵadvance(5);
241
- i0.ɵɵtextInterpolate(ctx_r1.record.Status);
242
- i0.ɵɵadvance(5);
243
- i0.ɵɵtextInterpolate(ctx_r1.record.RunByUser);
244
- i0.ɵɵadvance(5);
245
- i0.ɵɵtextInterpolate(ctx_r1.record.Environment || "N/A");
246
- i0.ɵɵadvance(5);
247
- i0.ɵɵtextInterpolate(ctx_r1.record.TriggerType || "N/A");
248
- i0.ɵɵadvance(5);
249
- i0.ɵɵtextInterpolate(ctx_r1.record.GitCommit || "N/A");
250
- i0.ɵɵadvance(5);
251
- i0.ɵɵtextInterpolate(ctx_r1.record.AgentVersion || "N/A");
1348
+ i0.ɵɵtext(31, "-");
1349
+ i0.ɵɵelementStart(32, "kbd");
1350
+ i0.ɵɵtext(33, "5");
1351
+ i0.ɵɵelementEnd()()()()();
252
1352
  } }
1353
+ /** Settings key for keyboard shortcuts visibility */
1354
+ const SHORTCUTS_SETTINGS_KEY = '__mj.Testing.ShowKeyboardShortcuts';
253
1355
  let TestSuiteRunFormComponentExtended = class TestSuiteRunFormComponentExtended extends TestSuiteRunFormComponent {
254
- constructor(elementRef, sharedService, router, route, cdr) {
1356
+ constructor(elementRef, sharedService, router, route, cdr, testingDialogService, evalPrefsService, viewContainerRef) {
255
1357
  super(elementRef, sharedService, router, route, cdr);
256
1358
  this.router = router;
257
1359
  this.cdr = cdr;
1360
+ this.testingDialogService = testingDialogService;
1361
+ this.evalPrefsService = evalPrefsService;
1362
+ this.viewContainerRef = viewContainerRef;
258
1363
  this.destroy$ = new Subject();
259
1364
  // UI state
260
1365
  this.activeTab = 'overview';
261
1366
  this.loading = false;
1367
+ this.loadingTestRuns = false;
1368
+ this.loadingFeedbacks = false;
262
1369
  this.error = null;
263
1370
  this.testRunsLoaded = false;
1371
+ this.feedbacksLoaded = false;
1372
+ this.isRefreshing = false;
1373
+ this.autoRefreshEnabled = false;
264
1374
  // Related entities
265
1375
  this.testSuite = null;
266
1376
  this.testRuns = [];
1377
+ this.feedbacks = new Map();
1378
+ // Tags
1379
+ this.tags = [];
1380
+ this.newTag = '';
1381
+ this.editingTags = false;
1382
+ this.savingTags = false;
1383
+ // Inline feedback
1384
+ this.expandedRunId = null;
1385
+ this.inlineRating = 0;
1386
+ this.inlineHoverRating = 0;
1387
+ this.inlineIsCorrect = null;
1388
+ this.inlineComments = '';
1389
+ this.savingInlineFeedback = false;
1390
+ // Filter for test runs
1391
+ this.runStatusFilter = null;
1392
+ // Keyboard shortcuts
1393
+ this.keyboardShortcutsEnabled = true;
1394
+ this.showShortcuts = false; // Hidden by default
1395
+ this.shortcutsSettingEntity = null;
1396
+ this.metadata = new Metadata();
1397
+ // Evaluation system
1398
+ this.evalPreferences = {
1399
+ showExecution: true,
1400
+ showHuman: true,
1401
+ showAuto: false
1402
+ };
1403
+ this.testRunsWithFeedback = [];
1404
+ this.evaluationMetrics = null;
1405
+ this.needsReviewItems = [];
267
1406
  }
268
1407
  async ngOnInit() {
269
1408
  await super.ngOnInit();
1409
+ this.loadShortcutsSetting();
1410
+ // Subscribe to evaluation preferences
1411
+ this.evalPrefsService.preferences$
1412
+ .pipe(takeUntil(this.destroy$))
1413
+ .subscribe(prefs => {
1414
+ this.evalPreferences = prefs;
1415
+ this.cdr.markForCheck();
1416
+ });
270
1417
  if (this.record && this.record.ID) {
271
1418
  await this.loadRelatedData();
1419
+ this.parseTags();
1420
+ // Auto-refresh for running suite executions
1421
+ if (this.record.Status === 'Running' || this.record.Status === 'Pending') {
1422
+ this.startAutoRefresh();
1423
+ }
272
1424
  }
273
1425
  }
1426
+ parseTags() {
1427
+ this.tags = TagsHelper.parseTags(this.record.Tags);
1428
+ }
274
1429
  ngOnDestroy() {
275
1430
  this.destroy$.next();
276
1431
  this.destroy$.complete();
277
1432
  }
1433
+ // Keyboard shortcuts
1434
+ handleKeyboardShortcut(event) {
1435
+ if (!this.keyboardShortcutsEnabled)
1436
+ return;
1437
+ // Cmd/Ctrl + R: Refresh
1438
+ if ((event.metaKey || event.ctrlKey) && event.key === 'r' && !event.shiftKey) {
1439
+ event.preventDefault();
1440
+ this.refresh();
1441
+ return;
1442
+ }
1443
+ // Cmd/Ctrl + Shift + R: Re-run suite
1444
+ if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key === 'r') {
1445
+ event.preventDefault();
1446
+ this.reRunSuite();
1447
+ return;
1448
+ }
1449
+ // Number keys for tabs (1-4)
1450
+ if (!event.metaKey && !event.ctrlKey && !event.altKey) {
1451
+ switch (event.key) {
1452
+ case '1':
1453
+ this.changeTab('overview');
1454
+ break;
1455
+ case '2':
1456
+ this.changeTab('runs');
1457
+ break;
1458
+ case '3':
1459
+ this.changeTab('details');
1460
+ break;
1461
+ case '4':
1462
+ this.changeTab('analytics');
1463
+ break;
1464
+ }
1465
+ }
1466
+ }
1467
+ startAutoRefresh() {
1468
+ this.autoRefreshEnabled = true;
1469
+ interval(5000)
1470
+ .pipe(takeUntil(this.destroy$))
1471
+ .subscribe(() => {
1472
+ if (this.autoRefreshEnabled && (this.record.Status === 'Running' || this.record.Status === 'Pending')) {
1473
+ this.silentRefresh();
1474
+ }
1475
+ else {
1476
+ this.autoRefreshEnabled = false;
1477
+ }
1478
+ });
1479
+ }
1480
+ async silentRefresh() {
1481
+ try {
1482
+ await this.record.Load(this.record.ID);
1483
+ this.cdr.markForCheck();
1484
+ }
1485
+ catch {
1486
+ // Silently fail on auto-refresh
1487
+ }
1488
+ }
278
1489
  async loadRelatedData() {
279
1490
  this.loading = true;
1491
+ this.error = null;
280
1492
  try {
281
1493
  // Load test suite
282
1494
  if (this.record.SuiteID) {
@@ -290,16 +1502,22 @@ let TestSuiteRunFormComponentExtended = class TestSuiteRunFormComponentExtended
290
1502
  }
291
1503
  catch (error) {
292
1504
  console.error('Error loading related data:', error);
293
- this.error = 'Failed to load related data';
1505
+ this.error = 'Failed to load related data. Click to retry.';
294
1506
  }
295
1507
  finally {
296
1508
  this.loading = false;
297
1509
  this.cdr.markForCheck();
298
1510
  }
299
1511
  }
1512
+ async retryLoad() {
1513
+ this.error = null;
1514
+ await this.loadRelatedData();
1515
+ }
300
1516
  async loadTestRuns() {
301
1517
  if (this.testRunsLoaded)
302
1518
  return;
1519
+ this.loadingTestRuns = true;
1520
+ this.cdr.markForCheck();
303
1521
  try {
304
1522
  const rv = new RunView();
305
1523
  const result = await rv.RunView({
@@ -312,40 +1530,51 @@ let TestSuiteRunFormComponentExtended = class TestSuiteRunFormComponentExtended
312
1530
  this.testRuns = result.Results || [];
313
1531
  }
314
1532
  this.testRunsLoaded = true;
315
- this.cdr.markForCheck();
1533
+ // Also load feedbacks for these runs
1534
+ if (this.testRuns.length > 0) {
1535
+ await this.loadFeedbacks();
1536
+ }
316
1537
  }
317
1538
  catch (error) {
318
1539
  console.error('Error loading test runs:', error);
1540
+ SharedService.Instance.CreateSimpleNotification('Failed to load test runs', 'error', 3000);
1541
+ }
1542
+ finally {
1543
+ this.loadingTestRuns = false;
1544
+ this.cdr.markForCheck();
319
1545
  }
320
1546
  }
321
1547
  changeTab(tab) {
322
1548
  this.activeTab = tab;
323
1549
  // Lazy load tabs
324
- if (tab === 'runs' && !this.testRunsLoaded) {
1550
+ if ((tab === 'runs' || tab === 'analytics') && !this.testRunsLoaded) {
325
1551
  this.loadTestRuns();
326
1552
  }
327
1553
  this.cdr.markForCheck();
328
1554
  }
329
1555
  getStatusColor() {
330
1556
  switch (this.record.Status) {
331
- case 'Completed': return '#4caf50';
332
- case 'Failed': return '#f44336';
333
- case 'Running': return '#2196f3';
334
- case 'Pending': return '#ffc107';
335
- case 'Cancelled': return '#9e9e9e';
336
- default: return '#999';
1557
+ case 'Completed': return '#10b981';
1558
+ case 'Failed': return '#ef4444';
1559
+ case 'Running': return '#3b82f6';
1560
+ case 'Pending': return '#8b5cf6';
1561
+ case 'Cancelled': return '#6b7280';
1562
+ default: return '#9ca3af';
337
1563
  }
338
1564
  }
339
1565
  getStatusIcon() {
340
1566
  switch (this.record.Status) {
341
1567
  case 'Completed': return 'fa-check-circle';
342
1568
  case 'Failed': return 'fa-times-circle';
343
- case 'Running': return 'fa-spinner fa-spin';
344
- case 'Pending': return 'fa-clock';
1569
+ case 'Running': return 'fa-circle-notch fa-spin';
1570
+ case 'Pending': return 'fa-hourglass-half';
345
1571
  case 'Cancelled': return 'fa-ban';
346
1572
  default: return 'fa-question-circle';
347
1573
  }
348
1574
  }
1575
+ getStatusClass() {
1576
+ return `status-${this.record.Status?.toLowerCase() || 'unknown'}`;
1577
+ }
349
1578
  calculateDuration() {
350
1579
  if (!this.record.TotalDurationSeconds)
351
1580
  return 'N/A';
@@ -373,6 +1602,25 @@ let TestSuiteRunFormComponentExtended = class TestSuiteRunFormComponentExtended
373
1602
  return 0;
374
1603
  return (passed / total) * 100;
375
1604
  }
1605
+ getRelativeTime(date) {
1606
+ if (!date)
1607
+ return 'N/A';
1608
+ const d = new Date(date);
1609
+ const now = new Date();
1610
+ const diffMs = now.getTime() - d.getTime();
1611
+ const diffMins = Math.floor(diffMs / 60000);
1612
+ const diffHours = Math.floor(diffMs / 3600000);
1613
+ const diffDays = Math.floor(diffMs / 86400000);
1614
+ if (diffMins < 1)
1615
+ return 'Just now';
1616
+ if (diffMins < 60)
1617
+ return `${diffMins}m ago`;
1618
+ if (diffHours < 24)
1619
+ return `${diffHours}h ago`;
1620
+ if (diffDays < 7)
1621
+ return `${diffDays}d ago`;
1622
+ return d.toLocaleDateString();
1623
+ }
376
1624
  openTestSuite() {
377
1625
  if (this.testSuite) {
378
1626
  SharedService.Instance.OpenEntityRecord('MJ: Test Suites', CompositeKey.FromID(this.testSuite.ID));
@@ -381,136 +1629,572 @@ let TestSuiteRunFormComponentExtended = class TestSuiteRunFormComponentExtended
381
1629
  openTestRun(runId) {
382
1630
  SharedService.Instance.OpenEntityRecord('MJ: Test Runs', CompositeKey.FromID(runId));
383
1631
  }
1632
+ async reRunSuite() {
1633
+ if (!this.record.SuiteID) {
1634
+ SharedService.Instance.CreateSimpleNotification('Cannot re-run: Suite ID not available', 'error', 3000);
1635
+ return;
1636
+ }
1637
+ this.testingDialogService.OpenSuiteDialog(this.record.SuiteID, this.viewContainerRef);
1638
+ }
384
1639
  async refresh() {
385
- await this.loadRelatedData();
386
- if (this.testRunsLoaded) {
387
- this.testRunsLoaded = false;
388
- await this.loadTestRuns();
1640
+ this.isRefreshing = true;
1641
+ this.cdr.markForCheck();
1642
+ try {
1643
+ await this.record.Load(this.record.ID);
1644
+ await this.loadRelatedData();
1645
+ // Reset lazy-loaded data
1646
+ if (this.testRunsLoaded) {
1647
+ this.testRunsLoaded = false;
1648
+ this.testRuns = [];
1649
+ await this.loadTestRuns();
1650
+ }
1651
+ SharedService.Instance.CreateSimpleNotification('Refreshed successfully', 'success', 2000);
1652
+ }
1653
+ catch {
1654
+ SharedService.Instance.CreateSimpleNotification('Failed to refresh', 'error', 3000);
1655
+ }
1656
+ finally {
1657
+ this.isRefreshing = false;
1658
+ this.cdr.markForCheck();
1659
+ }
1660
+ }
1661
+ getRunStatusColor(status) {
1662
+ switch (status) {
1663
+ case 'Passed': return '#10b981';
1664
+ case 'Failed': return '#ef4444';
1665
+ case 'Error': return '#f59e0b';
1666
+ case 'Timeout': return '#f97316';
1667
+ case 'Running': return '#3b82f6';
1668
+ case 'Pending': return '#8b5cf6';
1669
+ case 'Skipped': return '#6b7280';
1670
+ default: return '#9ca3af';
1671
+ }
1672
+ }
1673
+ getRunStatusIcon(status) {
1674
+ switch (status) {
1675
+ case 'Passed': return 'fa-check';
1676
+ case 'Failed': return 'fa-times';
1677
+ case 'Error': return 'fa-exclamation';
1678
+ case 'Timeout': return 'fa-clock';
1679
+ case 'Running': return 'fa-circle-notch fa-spin';
1680
+ case 'Pending': return 'fa-hourglass-half';
1681
+ case 'Skipped': return 'fa-forward';
1682
+ default: return 'fa-question';
1683
+ }
1684
+ }
1685
+ // ===========================
1686
+ // Tag Management
1687
+ // ===========================
1688
+ startEditingTags() {
1689
+ this.editingTags = true;
1690
+ this.cdr.markForCheck();
1691
+ }
1692
+ cancelEditingTags() {
1693
+ this.editingTags = false;
1694
+ this.newTag = '';
1695
+ this.parseTags(); // Reset to original
1696
+ this.cdr.markForCheck();
1697
+ }
1698
+ addTag() {
1699
+ const tag = this.newTag.trim();
1700
+ if (tag && !this.tags.includes(tag)) {
1701
+ this.tags = [...this.tags, tag];
1702
+ this.newTag = '';
1703
+ this.cdr.markForCheck();
1704
+ }
1705
+ }
1706
+ removeTag(tag) {
1707
+ this.tags = this.tags.filter(t => t !== tag);
1708
+ this.cdr.markForCheck();
1709
+ }
1710
+ async saveTags() {
1711
+ // Auto-add any pending tag in the input before saving
1712
+ const pendingTag = this.newTag.trim();
1713
+ if (pendingTag && !this.tags.includes(pendingTag)) {
1714
+ this.tags = [...this.tags, pendingTag];
1715
+ this.newTag = '';
1716
+ }
1717
+ this.savingTags = true;
1718
+ this.cdr.markForCheck();
1719
+ try {
1720
+ this.record.Tags = TagsHelper.toJson(this.tags);
1721
+ const result = await this.record.Save();
1722
+ if (result) {
1723
+ this.editingTags = false;
1724
+ SharedService.Instance.CreateSimpleNotification('Tags saved successfully', 'success', 2000);
1725
+ }
1726
+ else {
1727
+ SharedService.Instance.CreateSimpleNotification(this.record.LatestResult?.Message || 'Failed to save tags', 'error', 3000);
1728
+ }
1729
+ }
1730
+ catch (error) {
1731
+ SharedService.Instance.CreateSimpleNotification('Failed to save tags', 'error', 3000);
1732
+ }
1733
+ finally {
1734
+ this.savingTags = false;
1735
+ this.cdr.markForCheck();
1736
+ }
1737
+ }
1738
+ // ===========================
1739
+ // Test Run Filtering
1740
+ // ===========================
1741
+ setRunStatusFilter(status) {
1742
+ this.runStatusFilter = status;
1743
+ this.cdr.markForCheck();
1744
+ }
1745
+ getFilteredTestRuns() {
1746
+ if (!this.runStatusFilter)
1747
+ return this.testRuns;
1748
+ return this.testRuns.filter(run => run.Status === this.runStatusFilter);
1749
+ }
1750
+ getRunCountByStatus(status) {
1751
+ return this.testRuns.filter(run => run.Status === status).length;
1752
+ }
1753
+ // ===========================
1754
+ // Inline Feedback
1755
+ // ===========================
1756
+ async loadFeedbacks() {
1757
+ if (this.feedbacksLoaded)
1758
+ return;
1759
+ this.loadingFeedbacks = true;
1760
+ this.cdr.markForCheck();
1761
+ try {
1762
+ const testRunIds = this.testRuns.map(r => `'${r.ID}'`).join(',');
1763
+ if (!testRunIds)
1764
+ return;
1765
+ const rv = new RunView();
1766
+ const result = await rv.RunView({
1767
+ EntityName: 'MJ: Test Run Feedbacks',
1768
+ ExtraFilter: `TestRunID IN (${testRunIds})`,
1769
+ ResultType: 'entity_object'
1770
+ });
1771
+ if (result.Success && result.Results) {
1772
+ this.feedbacks.clear();
1773
+ for (const feedback of result.Results) {
1774
+ this.feedbacks.set(feedback.TestRunID, feedback);
1775
+ }
1776
+ }
1777
+ // Build TestRunWithFeedback array and calculate metrics
1778
+ this.buildTestRunsWithFeedback();
1779
+ this.feedbacksLoaded = true;
1780
+ }
1781
+ catch (error) {
1782
+ console.error('Error loading feedbacks:', error);
1783
+ }
1784
+ finally {
1785
+ this.loadingFeedbacks = false;
1786
+ this.cdr.markForCheck();
1787
+ }
1788
+ }
1789
+ /**
1790
+ * Build TestRunWithFeedback array from testRuns and feedbacks
1791
+ */
1792
+ buildTestRunsWithFeedback() {
1793
+ this.testRunsWithFeedback = this.testRuns.map(run => {
1794
+ const feedback = this.feedbacks.get(run.ID);
1795
+ return {
1796
+ id: run.ID,
1797
+ testId: run.TestID,
1798
+ testName: run.Test || 'Unknown Test',
1799
+ executionStatus: normalizeExecutionStatus(run.Status || 'Completed'),
1800
+ originalStatus: run.Status || 'Completed',
1801
+ duration: (run.DurationSeconds || 0) * 1000, // Convert to ms
1802
+ cost: run.CostUSD || 0,
1803
+ runDateTime: run.StartedAt ? new Date(run.StartedAt) : new Date(),
1804
+ autoScore: run.Score,
1805
+ passedChecks: null,
1806
+ failedChecks: null,
1807
+ totalChecks: null,
1808
+ humanRating: feedback?.Rating || null,
1809
+ humanIsCorrect: feedback?.IsCorrect ?? null,
1810
+ humanComments: feedback?.CorrectionSummary || null,
1811
+ hasHumanFeedback: !!feedback,
1812
+ feedbackId: feedback?.ID || null,
1813
+ tags: TagsHelper.parseTags(run.Tags),
1814
+ targetType: null,
1815
+ targetLogID: null
1816
+ };
1817
+ });
1818
+ // Calculate metrics
1819
+ this.evaluationMetrics = calculateEvaluationMetrics(this.testRunsWithFeedback);
1820
+ // Get items needing review
1821
+ this.needsReviewItems = getNeedsReviewItems(this.testRunsWithFeedback);
1822
+ }
1823
+ toggleRunExpanded(runId) {
1824
+ if (this.expandedRunId === runId) {
1825
+ this.expandedRunId = null;
1826
+ }
1827
+ else {
1828
+ this.expandedRunId = runId;
1829
+ this.initializeInlineFeedback(runId);
1830
+ }
1831
+ this.cdr.markForCheck();
1832
+ }
1833
+ initializeInlineFeedback(runId) {
1834
+ const existingFeedback = this.feedbacks.get(runId);
1835
+ if (existingFeedback) {
1836
+ this.inlineRating = existingFeedback.Rating || 0;
1837
+ this.inlineIsCorrect = existingFeedback.IsCorrect;
1838
+ this.inlineComments = existingFeedback.CorrectionSummary || '';
1839
+ }
1840
+ else {
1841
+ this.inlineRating = 0;
1842
+ this.inlineIsCorrect = null;
1843
+ this.inlineComments = '';
1844
+ }
1845
+ this.inlineHoverRating = 0;
1846
+ }
1847
+ setInlineRating(value) {
1848
+ this.inlineRating = value;
1849
+ this.cdr.markForCheck();
1850
+ }
1851
+ getInlineRatingLabel() {
1852
+ if (this.inlineRating <= 3)
1853
+ return 'Poor';
1854
+ if (this.inlineRating <= 5)
1855
+ return 'Below Average';
1856
+ if (this.inlineRating <= 6)
1857
+ return 'Average';
1858
+ if (this.inlineRating <= 7)
1859
+ return 'Good';
1860
+ if (this.inlineRating <= 8)
1861
+ return 'Very Good';
1862
+ if (this.inlineRating <= 9)
1863
+ return 'Excellent';
1864
+ return 'Outstanding';
1865
+ }
1866
+ canSubmitInlineFeedback() {
1867
+ return this.inlineRating > 0 && this.inlineComments.trim().length > 0;
1868
+ }
1869
+ async saveInlineFeedback() {
1870
+ if (!this.expandedRunId || !this.canSubmitInlineFeedback())
1871
+ return;
1872
+ this.savingInlineFeedback = true;
1873
+ this.cdr.markForCheck();
1874
+ try {
1875
+ const md = new Metadata();
1876
+ const currentUser = md.CurrentUser;
1877
+ let feedback = this.feedbacks.get(this.expandedRunId);
1878
+ if (!feedback) {
1879
+ feedback = await md.GetEntityObject('MJ: Test Run Feedbacks', currentUser);
1880
+ feedback.TestRunID = this.expandedRunId;
1881
+ feedback.ReviewerUserID = currentUser.ID;
1882
+ }
1883
+ feedback.Rating = this.inlineRating;
1884
+ feedback.IsCorrect = this.inlineIsCorrect;
1885
+ feedback.CorrectionSummary = this.inlineComments.trim() || null;
1886
+ const result = await feedback.Save();
1887
+ if (result) {
1888
+ this.feedbacks.set(this.expandedRunId, feedback);
1889
+ // Rebuild the metrics after feedback update
1890
+ this.buildTestRunsWithFeedback();
1891
+ SharedService.Instance.CreateSimpleNotification('Feedback saved', 'success', 2000);
1892
+ this.expandedRunId = null;
1893
+ }
1894
+ else {
1895
+ SharedService.Instance.CreateSimpleNotification(feedback.LatestResult?.Message || 'Failed to save feedback', 'error', 3000);
1896
+ }
1897
+ }
1898
+ catch (error) {
1899
+ SharedService.Instance.CreateSimpleNotification('Failed to save feedback', 'error', 3000);
1900
+ }
1901
+ finally {
1902
+ this.savingInlineFeedback = false;
1903
+ this.cdr.markForCheck();
1904
+ }
1905
+ }
1906
+ hasFeedback(runId) {
1907
+ return this.feedbacks.has(runId);
1908
+ }
1909
+ getFeedbackRating(runId) {
1910
+ return this.feedbacks.get(runId)?.Rating || 0;
1911
+ }
1912
+ /**
1913
+ * Get TestRunWithFeedback by run ID for template binding
1914
+ */
1915
+ getRunWithFeedback(runId) {
1916
+ return this.testRunsWithFeedback.find(r => r.id === runId);
1917
+ }
1918
+ /**
1919
+ * Get the human correctness status for a run
1920
+ */
1921
+ getHumanIsCorrect(runId) {
1922
+ return this.feedbacks.get(runId)?.IsCorrect ?? null;
1923
+ }
1924
+ // ===========================
1925
+ // Run Tags
1926
+ // ===========================
1927
+ getRunTags(run) {
1928
+ return TagsHelper.parseTags(run.Tags);
1929
+ }
1930
+ // ===========================
1931
+ // Keyboard Shortcuts Settings
1932
+ // ===========================
1933
+ /**
1934
+ * Load keyboard shortcuts visibility setting from user settings
1935
+ */
1936
+ loadShortcutsSetting() {
1937
+ try {
1938
+ const engine = UserInfoEngine.Instance;
1939
+ const setting = engine.UserSettings.find(s => s.Setting === SHORTCUTS_SETTINGS_KEY);
1940
+ if (setting) {
1941
+ this.shortcutsSettingEntity = setting;
1942
+ this.showShortcuts = setting.Value === 'true';
1943
+ }
1944
+ else {
1945
+ // Default to hidden
1946
+ this.showShortcuts = false;
1947
+ }
1948
+ this.cdr.markForCheck();
1949
+ }
1950
+ catch (error) {
1951
+ console.warn('Failed to load shortcuts setting:', error);
389
1952
  }
1953
+ }
1954
+ /**
1955
+ * Toggle keyboard shortcuts visibility and save preference
1956
+ */
1957
+ async toggleShortcuts() {
1958
+ this.showShortcuts = !this.showShortcuts;
390
1959
  this.cdr.markForCheck();
1960
+ try {
1961
+ const userId = this.metadata.CurrentUser?.ID;
1962
+ if (!userId)
1963
+ return;
1964
+ if (!this.shortcutsSettingEntity) {
1965
+ const engine = UserInfoEngine.Instance;
1966
+ const setting = engine.UserSettings.find(s => s.Setting === SHORTCUTS_SETTINGS_KEY);
1967
+ if (setting) {
1968
+ this.shortcutsSettingEntity = setting;
1969
+ }
1970
+ else {
1971
+ this.shortcutsSettingEntity = await this.metadata.GetEntityObject('MJ: User Settings');
1972
+ this.shortcutsSettingEntity.UserID = userId;
1973
+ this.shortcutsSettingEntity.Setting = SHORTCUTS_SETTINGS_KEY;
1974
+ }
1975
+ }
1976
+ this.shortcutsSettingEntity.Value = this.showShortcuts ? 'true' : 'false';
1977
+ await this.shortcutsSettingEntity.Save();
1978
+ }
1979
+ catch (error) {
1980
+ console.warn('Failed to save shortcuts setting:', error);
1981
+ }
1982
+ }
1983
+ // ===========================
1984
+ // Analytics Calculations
1985
+ // ===========================
1986
+ getPassedCount() {
1987
+ return this.testRuns.filter(r => r.Status === 'Passed').length;
1988
+ }
1989
+ getFailedCount() {
1990
+ return this.testRuns.filter(r => r.Status === 'Failed' || r.Status === 'Error').length;
1991
+ }
1992
+ getPassedPercent() {
1993
+ if (this.testRuns.length === 0)
1994
+ return 0;
1995
+ return (this.getPassedCount() / this.testRuns.length) * 100;
1996
+ }
1997
+ getFailedPercent() {
1998
+ if (this.testRuns.length === 0)
1999
+ return 0;
2000
+ return (this.getFailedCount() / this.testRuns.length) * 100;
2001
+ }
2002
+ getAverageScore() {
2003
+ const runsWithScore = this.testRuns.filter(r => r.Score != null);
2004
+ if (runsWithScore.length === 0)
2005
+ return 0;
2006
+ const sum = runsWithScore.reduce((acc, r) => acc + (r.Score || 0), 0);
2007
+ return sum / runsWithScore.length;
2008
+ }
2009
+ getAverageDuration() {
2010
+ const runsWithDuration = this.testRuns.filter(r => r.DurationSeconds != null);
2011
+ if (runsWithDuration.length === 0)
2012
+ return 0;
2013
+ const sum = runsWithDuration.reduce((acc, r) => acc + (r.DurationSeconds || 0), 0);
2014
+ return sum / runsWithDuration.length;
2015
+ }
2016
+ getTotalCost() {
2017
+ return this.testRuns.reduce((acc, r) => acc + (r.CostUSD || 0), 0);
2018
+ }
2019
+ // ===========================
2020
+ // Export
2021
+ // ===========================
2022
+ exportToCSV() {
2023
+ const headers = ['Test Name', 'Status', 'Score', 'Duration (s)', 'Cost (USD)', 'Started At', 'Tags'];
2024
+ const rows = this.testRuns.map(run => [
2025
+ run.Test || '',
2026
+ run.Status || '',
2027
+ run.Score?.toFixed(4) || '',
2028
+ run.DurationSeconds?.toFixed(2) || '',
2029
+ run.CostUSD?.toFixed(6) || '',
2030
+ run.StartedAt ? new Date(run.StartedAt).toISOString() : '',
2031
+ this.getRunTags(run).join('; ')
2032
+ ]);
2033
+ const csvContent = [headers, ...rows]
2034
+ .map(row => row.map(cell => `"${cell}"`).join(','))
2035
+ .join('\n');
2036
+ const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
2037
+ const link = document.createElement('a');
2038
+ link.href = URL.createObjectURL(blob);
2039
+ link.download = `test-suite-run-${this.record.ID.substring(0, 8)}-results.csv`;
2040
+ link.click();
2041
+ URL.revokeObjectURL(link.href);
2042
+ SharedService.Instance.CreateSimpleNotification('Export complete', 'success', 2000);
391
2043
  }
392
- static { this.ɵfac = function TestSuiteRunFormComponentExtended_Factory(t) { return new (t || TestSuiteRunFormComponentExtended)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i2.ActivatedRoute), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
393
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestSuiteRunFormComponentExtended, selectors: [["mj-test-suite-run-form"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 97, vars: 35, consts: [[1, "test-suite-run-form"], [1, "suite-run-header"], ["class", "breadcrumb", 4, "ngIf"], [1, "header-content"], [1, "header-left"], [1, "suite-run-icon"], [1, "fas", "fa-layer-group"], [1, "suite-run-info"], [1, "suite-run-meta"], [1, "status-badge"], [1, "fas", 3, "ngClass"], ["class", "environment", 4, "ngIf"], ["class", "trigger", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "icon", "sync", 3, "click"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-label"], [1, "metric-value"], [1, "results-summary"], [1, "result-item", "passed"], [1, "fas", "fa-check-circle"], [1, "count"], [1, "label"], [1, "result-item", "failed"], [1, "fas", "fa-times-circle"], [1, "result-item", "skipped"], [1, "fas", "fa-forward"], [1, "result-item", "error"], [1, "fas", "fa-exclamation-circle"], [1, "result-item", "total"], [1, "fas", "fa-list"], [1, "tabs-container"], [1, "tabs"], [1, "tab", 3, "click"], [1, "fas", "fa-th-large"], ["class", "tab-badge", 4, "ngIf"], [1, "fas", "fa-info-circle"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "runs-tab", 4, "ngIf"], ["class", "details-tab", 4, "ngIf"], [1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-folder"], [1, "fas", "fa-chevron-right"], [1, "environment"], [1, "trigger"], [1, "tab-badge"], [1, "overview-tab"], [1, "result-hero"], [1, "result-icon"], [1, "result-text"], [1, "result-stats"], [1, "result-counts"], [1, "runs-tab"], ["class", "test-runs-list", 4, "ngIf"], ["class", "no-data", 4, "ngIf"], [1, "test-runs-list"], ["class", "test-run-item", 3, "click", 4, "ngFor", "ngForOf"], [1, "test-run-item", 3, "click"], [1, "run-sequence"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-name"], [1, "run-meta"], [1, "status"], [4, "ngIf"], [1, "no-data"], [1, "fas", "fa-inbox"], [1, "details-tab"], [1, "details-grid"], [1, "detail-item"], [1, "detail-label"], [1, "detail-value"], ["href", "javascript:void(0)", 3, "click", 4, "ngIf"]], template: function TestSuiteRunFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
2044
+ static { this.ɵfac = function TestSuiteRunFormComponentExtended_Factory(t) { return new (t || TestSuiteRunFormComponentExtended)(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(i3.EvaluationPreferencesService), i0.ɵɵdirectiveInject(i0.ViewContainerRef)); }; }
2045
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestSuiteRunFormComponentExtended, selectors: [["mj-test-suite-run-form"]], hostBindings: function TestSuiteRunFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
2046
+ i0.ɵɵlistener("keydown", function TestSuiteRunFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, false, i0.ɵɵresolveDocument);
2047
+ } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 126, vars: 47, consts: [["kendoDialogContainer", "", 1, "test-suite-run-form"], [1, "suite-run-header"], ["class", "breadcrumb", 4, "ngIf"], [1, "header-content"], [1, "header-left"], [1, "suite-run-icon"], [1, "fas", 3, "ngClass"], [1, "suite-run-info"], [1, "suite-run-meta"], [1, "status-badge", 3, "ngClass"], ["class", "meta-tag environment", 4, "ngIf"], ["class", "meta-tag trigger", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "themeColor", "primary", 3, "click", 4, "ngIf"], ["kendoButton", "", 3, "click", "disabled"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-icon"], [1, "fas", "fa-clock"], [1, "metric-content"], [1, "metric-value"], [1, "metric-label"], [1, "fas", "fa-percentage"], [1, "fas", "fa-dollar-sign"], [1, "fas", "fa-calendar"], [1, "results-summary"], [1, "result-item", "passed"], [1, "result-icon"], [1, "fas", "fa-check-circle"], [1, "result-content"], [1, "result-count"], [1, "result-label"], [1, "result-item", "failed"], [1, "fas", "fa-times-circle"], [1, "result-item", "error"], [1, "fas", "fa-exclamation-circle"], [1, "result-item", "skipped"], [1, "fas", "fa-forward"], [1, "result-item", "total"], [1, "fas", "fa-list"], ["class", "tags-bar", 4, "ngIf"], ["class", "tags-editor-panel", 4, "ngIf"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], ["class", "tab-badge", 4, "ngIf"], [1, "fas", "fa-info-circle"], ["role", "tab", "title", "Press 4", 1, "tab", 3, "click"], [1, "fas", "fa-chart-bar"], ["role", "tab", "title", "Press 5", 1, "tab", 3, "click"], [1, "fas", "fa-microchip"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "runs-tab", 4, "ngIf"], ["class", "details-tab", 4, "ngIf"], ["class", "analytics-tab", 4, "ngIf"], ["class", "execution-tab", 4, "ngIf"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], ["class", "keyboard-shortcuts", 4, "ngIf"], [1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-layer-group"], [1, "fas", "fa-chevron-right", "separator"], [1, "current"], [1, "meta-tag", "environment"], [1, "fas", "fa-server"], [1, "meta-tag", "trigger"], [1, "fas", "fa-bolt"], ["kendoButton", "", "themeColor", "primary", 3, "click"], [1, "fas", "fa-play"], [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"], [1, "overview-tab"], [1, "result-hero"], [1, "result-hero-icon"], [1, "result-hero-text"], [1, "result-hero-stats"], [1, "stat-item"], [1, "stat-value"], [1, "stat-label"], [1, "stat-divider"], ["class", "evaluation-summary", 4, "ngIf"], ["class", "needs-review-section", 4, "ngIf"], ["class", "progress-section", 4, "ngIf"], [1, "evaluation-summary"], [1, "eval-summary-grid"], ["class", "eval-summary-card", 4, "ngIf"], [1, "eval-summary-card"], [1, "eval-card-header"], [1, "fa-solid", "fa-user"], [1, "eval-card-body"], [1, "eval-stat-row"], [1, "eval-stat-label"], [1, "eval-stat-value"], ["class", "eval-stat-row", 4, "ngIf"], ["class", "eval-card-footer", 4, "ngIf"], [1, "eval-stat-value", "correct"], ["class", "eval-stat-value incorrect", 4, "ngIf"], [1, "eval-stat-value", "incorrect"], [1, "eval-card-footer"], [1, "pending-badge"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-robot"], [1, "fa-solid", "fa-circle-check"], ["class", "eval-stat-value error", 4, "ngIf"], ["class", "eval-stat-value timeout", 4, "ngIf"], [1, "eval-stat-value", "error"], [1, "eval-stat-value", "timeout"], [1, "needs-review-section"], [1, "needs-review-header"], [1, "fa-solid", "fa-user-clock"], [1, "review-count"], [1, "needs-review-list"], ["class", "review-item", 3, "high-priority", "medium-priority", "click", 4, "ngFor", "ngForOf"], ["class", "review-more", 4, "ngIf"], [1, "review-item", 3, "click"], [1, "review-item-icon"], ["class", "fa-solid fa-exclamation-triangle", 4, "ngIf"], ["class", "fa-solid fa-circle-dot", 4, "ngIf"], ["class", "fa-solid fa-clock", 4, "ngIf"], [1, "review-item-content"], [1, "review-item-name"], [1, "review-item-reason"], [1, "review-item-action"], [1, "fa-solid", "fa-chevron-right"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "fa-solid", "fa-circle-dot"], [1, "review-more"], [1, "progress-section"], [1, "progress-info"], [1, "fas", "fa-circle-notch", "fa-spin"], [1, "auto-refresh-notice"], [1, "fas", "fa-sync"], [1, "runs-tab"], ["class", "runs-toolbar", 4, "ngIf"], ["class", "loading-state", 4, "ngIf"], ["class", "test-runs-list", 4, "ngIf"], ["class", "empty-state", 4, "ngIf"], [1, "runs-toolbar"], [1, "run-filters"], [1, "filter-btn", 3, "click"], ["class", "filter-btn passed", 3, "active", "click", 4, "ngIf"], ["class", "filter-btn failed", 3, "active", "click", 4, "ngIf"], ["class", "filter-btn error", 3, "active", "click", 4, "ngIf"], [1, "runs-actions"], ["kendoButton", "", 3, "click"], [1, "fas", "fa-download"], [1, "filter-btn", "passed", 3, "click"], [1, "fas", "fa-check"], [1, "filter-btn", "failed", 3, "click"], [1, "filter-btn", "error", 3, "click"], [1, "fas", "fa-exclamation"], [1, "loading-state"], [1, "skeleton-list"], ["class", "skeleton-card", 4, "ngFor", "ngForOf"], [1, "skeleton-card"], [1, "skeleton-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "test-runs-list"], ["class", "test-run-card", 4, "ngFor", "ngForOf"], [1, "test-run-card"], [1, "test-run-item", 3, "click"], [1, "run-sequence"], [1, "run-icon"], [1, "run-content"], [1, "run-header-row"], [1, "run-name"], [3, "executionStatus", "originalStatus", "autoScore", "humanRating", "humanIsCorrect", "hasHumanFeedback", "preferences", "mode"], [1, "run-meta"], ["class", "run-duration", 4, "ngIf"], ["class", "run-cost", 4, "ngIf"], [3, "entityName", "recordId", 4, "ngIf"], ["class", "run-tags", 4, "ngIf"], [1, "run-expand"], [1, "fas"], ["class", "inline-feedback", 4, "ngIf"], [1, "run-duration"], [1, "run-cost"], [3, "entityName", "recordId"], [1, "run-tags"], ["class", "tag-chip", 4, "ngFor", "ngForOf"], [1, "tag-chip"], [1, "inline-feedback"], [1, "feedback-divider"], [1, "feedback-section"], [1, "feedback-label"], [1, "inline-rating"], [1, "rating-numbers"], ["type", "button", "class", "rating-btn", 3, "selected", "hover", "low", "mid", "high", "click", "mouseenter", "mouseleave", 4, "ngFor", "ngForOf"], ["class", "rating-info", 4, "ngIf"], [1, "correctness-row"], [1, "correctness-label"], [1, "correctness-options"], [1, "radio-opt", 3, "click"], ["type", "radio", 3, "ngModelChange", "name", "value", "ngModel"], [1, "comments-row", 3, "click"], ["placeholder", "Add comments or corrections...", "rows", "3", 1, "feedback-textarea", 3, "ngModelChange", "ngModel"], [1, "feedback-actions", 3, "click"], [1, "fas", "fa-external-link-alt"], ["type", "button", 1, "rating-btn", 3, "click", "mouseenter", "mouseleave"], [1, "rating-info"], [1, "rating-value"], [1, "rating-label-text"], [1, "empty-state"], [1, "empty-icon"], [1, "fas", "fa-inbox"], [1, "fas", "fa-filter"], [1, "details-tab"], [1, "details-card"], [1, "details-grid"], [1, "detail-item"], [1, "detail-label"], [1, "detail-value", "monospace"], [1, "detail-value"], ["href", "javascript:void(0)", 3, "click", 4, "ngIf"], [4, "ngIf"], [1, "status-inline", 3, "ngClass"], [1, "analytics-tab"], ["class", "analytics-loading", 4, "ngIf"], ["class", "analytics-section", 4, "ngIf"], [1, "analytics-loading"], [1, "analytics-section"], [1, "fas", "fa-chart-pie"], [1, "stats-grid"], [1, "stat-card"], [1, "stat-icon", "passed"], [1, "stat-content"], [1, "stat-percent"], [1, "stat-icon", "failed"], [1, "stat-icon", "score"], [1, "fas", "fa-star"], [1, "stat-icon", "duration"], [1, "stat-icon", "cost"], [1, "analytics-header"], [1, "fas", "fa-table"], [1, "analytics-legend"], [1, "legend-item", "passed"], [1, "legend-item", "failed"], [1, "legend-item", "error"], [1, "legend-item", "skipped"], [1, "results-table-wrapper"], [1, "results-table"], [1, "seq-col"], [1, "name-col"], ["class", "status-col", 4, "ngIf"], ["class", "score-col", 4, "ngIf"], ["class", "feedback-col", 4, "ngIf"], [1, "duration-col"], [1, "cost-col"], ["class", "result-row", 3, "row-passed", "row-failed", "row-error", "row-skipped", "click", 4, "ngFor", "ngForOf"], [1, "status-col"], [1, "score-col"], [1, "feedback-col"], [1, "result-row", 3, "click"], [1, "test-name-wrapper"], [1, "test-name"], ["class", "test-tags", 4, "ngIf"], ["class", "na-value", 4, "ngIf"], [1, "test-tags"], ["class", "tag-mini", 4, "ngFor", "ngForOf"], [1, "tag-mini"], ["class", "score-display", 4, "ngIf"], [1, "score-display"], [1, "score-bar-mini"], [1, "score-fill"], [1, "score-text"], [1, "na-value"], ["class", "feedback-display", 4, "ngIf"], ["class", "na-value needs-review", 4, "ngIf"], [1, "feedback-display"], [1, "feedback-rating"], ["class", "feedback-correctness", 4, "ngIf"], [1, "feedback-correctness"], [1, "na-value", "needs-review"], [1, "fas", "fa-user-clock"], [1, "execution-tab"], [3, "machineName", "machineId", "runByUserName", "runByUserEmail", "runContextDetailsJson"], [1, "keyboard-shortcuts"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"]], template: function TestSuiteRunFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
394
2048
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
395
2049
  i0.ɵɵtemplate(2, TestSuiteRunFormComponentExtended_div_2_Template, 7, 2, "div", 2);
396
2050
  i0.ɵɵelementStart(3, "div", 3)(4, "div", 4)(5, "div", 5);
397
2051
  i0.ɵɵelement(6, "i", 6);
398
2052
  i0.ɵɵelementEnd();
399
2053
  i0.ɵɵelementStart(7, "div", 7)(8, "h1");
400
- i0.ɵɵtext(9, "Test Suite Run");
2054
+ i0.ɵɵtext(9, "Suite Run");
401
2055
  i0.ɵɵelementEnd();
402
2056
  i0.ɵɵelementStart(10, "div", 8)(11, "span", 9);
403
- i0.ɵɵelement(12, "i", 10);
2057
+ i0.ɵɵelement(12, "i", 6);
404
2058
  i0.ɵɵtext(13);
405
2059
  i0.ɵɵelementEnd();
406
- i0.ɵɵtemplate(14, TestSuiteRunFormComponentExtended_span_14_Template, 2, 1, "span", 11)(15, TestSuiteRunFormComponentExtended_span_15_Template, 2, 1, "span", 12);
2060
+ i0.ɵɵtemplate(14, TestSuiteRunFormComponentExtended_span_14_Template, 3, 1, "span", 10)(15, TestSuiteRunFormComponentExtended_span_15_Template, 3, 1, "span", 11);
407
2061
  i0.ɵɵelementEnd()()();
408
- i0.ɵɵelementStart(16, "div", 13)(17, "button", 14);
409
- i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_17_listener() { return ctx.refresh(); });
410
- i0.ɵɵtext(18, " Refresh ");
2062
+ i0.ɵɵelementStart(16, "div", 12);
2063
+ i0.ɵɵelement(17, "app-evaluation-mode-toggle");
2064
+ i0.ɵɵtemplate(18, TestSuiteRunFormComponentExtended_button_18_Template, 3, 0, "button", 13);
2065
+ i0.ɵɵelementStart(19, "button", 14);
2066
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_19_listener() { return ctx.refresh(); });
2067
+ i0.ɵɵelement(20, "i", 6);
2068
+ i0.ɵɵtext(21);
411
2069
  i0.ɵɵelementEnd()()();
412
- i0.ɵɵelementStart(19, "div", 15)(20, "div", 16)(21, "div", 17);
413
- i0.ɵɵtext(22, "Started");
2070
+ i0.ɵɵelementStart(22, "div", 15)(23, "div", 16)(24, "div", 17);
2071
+ i0.ɵɵelement(25, "i", 18);
414
2072
  i0.ɵɵelementEnd();
415
- i0.ɵɵelementStart(23, "div", 18);
416
- i0.ɵɵtext(24);
417
- i0.ɵɵpipe(25, "date");
418
- i0.ɵɵelementEnd()();
419
- i0.ɵɵelementStart(26, "div", 16)(27, "div", 17);
420
- i0.ɵɵtext(28, "Completed");
2073
+ i0.ɵɵelementStart(26, "div", 19)(27, "div", 20);
2074
+ i0.ɵɵtext(28);
421
2075
  i0.ɵɵelementEnd();
422
- i0.ɵɵelementStart(29, "div", 18);
423
- i0.ɵɵtext(30);
424
- i0.ɵɵpipe(31, "date");
425
- i0.ɵɵelementEnd()();
426
- i0.ɵɵelementStart(32, "div", 16)(33, "div", 17);
427
- i0.ɵɵtext(34, "Duration");
2076
+ i0.ɵɵelementStart(29, "div", 21);
2077
+ i0.ɵɵtext(30, "Duration");
2078
+ i0.ɵɵelementEnd()()();
2079
+ i0.ɵɵelementStart(31, "div", 16)(32, "div", 17);
2080
+ i0.ɵɵelement(33, "i", 22);
428
2081
  i0.ɵɵelementEnd();
429
- i0.ɵɵelementStart(35, "div", 18);
2082
+ i0.ɵɵelementStart(34, "div", 19)(35, "div", 20);
430
2083
  i0.ɵɵtext(36);
431
- i0.ɵɵelementEnd()();
432
- i0.ɵɵelementStart(37, "div", 16)(38, "div", 17);
433
- i0.ɵɵtext(39, "Pass Rate");
434
2084
  i0.ɵɵelementEnd();
435
- i0.ɵɵelementStart(40, "div", 18);
436
- i0.ɵɵtext(41);
437
- i0.ɵɵelementEnd()();
438
- i0.ɵɵelementStart(42, "div", 16)(43, "div", 17);
439
- i0.ɵɵtext(44, "Cost");
2085
+ i0.ɵɵelementStart(37, "div", 21);
2086
+ i0.ɵɵtext(38, "Pass Rate");
2087
+ i0.ɵɵelementEnd()()();
2088
+ i0.ɵɵelementStart(39, "div", 16)(40, "div", 17);
2089
+ i0.ɵɵelement(41, "i", 23);
2090
+ i0.ɵɵelementEnd();
2091
+ i0.ɵɵelementStart(42, "div", 19)(43, "div", 20);
2092
+ i0.ɵɵtext(44);
440
2093
  i0.ɵɵelementEnd();
441
- i0.ɵɵelementStart(45, "div", 18);
442
- i0.ɵɵtext(46);
2094
+ i0.ɵɵelementStart(45, "div", 21);
2095
+ i0.ɵɵtext(46, "Total Cost");
443
2096
  i0.ɵɵelementEnd()()();
444
- i0.ɵɵelementStart(47, "div", 19)(48, "div", 20);
445
- i0.ɵɵelement(49, "i", 21);
446
- i0.ɵɵelementStart(50, "span", 22);
447
- i0.ɵɵtext(51);
2097
+ i0.ɵɵelementStart(47, "div", 16)(48, "div", 17);
2098
+ i0.ɵɵelement(49, "i", 24);
2099
+ i0.ɵɵelementEnd();
2100
+ i0.ɵɵelementStart(50, "div", 19)(51, "div", 20);
2101
+ i0.ɵɵtext(52);
448
2102
  i0.ɵɵelementEnd();
449
- i0.ɵɵelementStart(52, "span", 23);
450
- i0.ɵɵtext(53, "Passed");
451
- i0.ɵɵelementEnd()();
452
- i0.ɵɵelementStart(54, "div", 24);
453
- i0.ɵɵelement(55, "i", 25);
454
- i0.ɵɵelementStart(56, "span", 22);
455
- i0.ɵɵtext(57);
2103
+ i0.ɵɵelementStart(53, "div", 21);
2104
+ i0.ɵɵtext(54, "Started");
2105
+ i0.ɵɵelementEnd()()()();
2106
+ i0.ɵɵelementStart(55, "div", 25)(56, "div", 26)(57, "div", 27);
2107
+ i0.ɵɵelement(58, "i", 28);
2108
+ i0.ɵɵelementEnd();
2109
+ i0.ɵɵelementStart(59, "div", 29)(60, "span", 30);
2110
+ i0.ɵɵtext(61);
456
2111
  i0.ɵɵelementEnd();
457
- i0.ɵɵelementStart(58, "span", 23);
458
- i0.ɵɵtext(59, "Failed");
459
- i0.ɵɵelementEnd()();
460
- i0.ɵɵelementStart(60, "div", 26);
461
- i0.ɵɵelement(61, "i", 27);
462
- i0.ɵɵelementStart(62, "span", 22);
463
- i0.ɵɵtext(63);
2112
+ i0.ɵɵelementStart(62, "span", 31);
2113
+ i0.ɵɵtext(63, "Passed");
2114
+ i0.ɵɵelementEnd()()();
2115
+ i0.ɵɵelementStart(64, "div", 32)(65, "div", 27);
2116
+ i0.ɵɵelement(66, "i", 33);
464
2117
  i0.ɵɵelementEnd();
465
- i0.ɵɵelementStart(64, "span", 23);
466
- i0.ɵɵtext(65, "Skipped");
467
- i0.ɵɵelementEnd()();
468
- i0.ɵɵelementStart(66, "div", 28);
469
- i0.ɵɵelement(67, "i", 29);
470
- i0.ɵɵelementStart(68, "span", 22);
2118
+ i0.ɵɵelementStart(67, "div", 29)(68, "span", 30);
471
2119
  i0.ɵɵtext(69);
472
2120
  i0.ɵɵelementEnd();
473
- i0.ɵɵelementStart(70, "span", 23);
474
- i0.ɵɵtext(71, "Errors");
475
- i0.ɵɵelementEnd()();
476
- i0.ɵɵelementStart(72, "div", 30);
477
- i0.ɵɵelement(73, "i", 31);
478
- i0.ɵɵelementStart(74, "span", 22);
479
- i0.ɵɵtext(75);
2121
+ i0.ɵɵelementStart(70, "span", 31);
2122
+ i0.ɵɵtext(71, "Failed");
2123
+ i0.ɵɵelementEnd()()();
2124
+ i0.ɵɵelementStart(72, "div", 34)(73, "div", 27);
2125
+ i0.ɵɵelement(74, "i", 35);
2126
+ i0.ɵɵelementEnd();
2127
+ i0.ɵɵelementStart(75, "div", 29)(76, "span", 30);
2128
+ i0.ɵɵtext(77);
2129
+ i0.ɵɵelementEnd();
2130
+ i0.ɵɵelementStart(78, "span", 31);
2131
+ i0.ɵɵtext(79, "Errors");
2132
+ i0.ɵɵelementEnd()()();
2133
+ i0.ɵɵelementStart(80, "div", 36)(81, "div", 27);
2134
+ i0.ɵɵelement(82, "i", 37);
2135
+ i0.ɵɵelementEnd();
2136
+ i0.ɵɵelementStart(83, "div", 29)(84, "span", 30);
2137
+ i0.ɵɵtext(85);
480
2138
  i0.ɵɵelementEnd();
481
- i0.ɵɵelementStart(76, "span", 23);
482
- i0.ɵɵtext(77, "Total");
2139
+ i0.ɵɵelementStart(86, "span", 31);
2140
+ i0.ɵɵtext(87, "Skipped");
2141
+ i0.ɵɵelementEnd()()();
2142
+ i0.ɵɵelementStart(88, "div", 38)(89, "div", 27);
2143
+ i0.ɵɵelement(90, "i", 39);
2144
+ i0.ɵɵelementEnd();
2145
+ i0.ɵɵelementStart(91, "div", 29)(92, "span", 30);
2146
+ i0.ɵɵtext(93);
2147
+ i0.ɵɵelementEnd();
2148
+ i0.ɵɵelementStart(94, "span", 31);
2149
+ i0.ɵɵtext(95, "Total");
483
2150
  i0.ɵɵelementEnd()()()();
484
- i0.ɵɵelementStart(78, "div", 32)(79, "div", 33)(80, "button", 34);
485
- i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_80_listener() { return ctx.changeTab("overview"); });
486
- i0.ɵɵelement(81, "i", 35);
487
- i0.ɵɵelementStart(82, "span");
488
- i0.ɵɵtext(83, "Overview");
489
- i0.ɵɵelementEnd()();
490
- i0.ɵɵelementStart(84, "button", 34);
491
- i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_84_listener() { return ctx.changeTab("runs"); });
492
- i0.ɵɵelement(85, "i", 31);
493
- i0.ɵɵelementStart(86, "span");
494
- i0.ɵɵtext(87, "Test Runs");
2151
+ i0.ɵɵtemplate(96, TestSuiteRunFormComponentExtended_div_96_Template, 9, 2, "div", 40)(97, TestSuiteRunFormComponentExtended_div_97_Template, 19, 7, "div", 41);
2152
+ i0.ɵɵelementEnd();
2153
+ i0.ɵɵelementStart(98, "div", 42)(99, "div", 43)(100, "button", 44);
2154
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_100_listener() { return ctx.changeTab("overview"); });
2155
+ i0.ɵɵelement(101, "i", 45);
2156
+ i0.ɵɵtext(102, " Overview ");
495
2157
  i0.ɵɵelementEnd();
496
- i0.ɵɵtemplate(88, TestSuiteRunFormComponentExtended_span_88_Template, 2, 1, "span", 36);
2158
+ i0.ɵɵelementStart(103, "button", 44);
2159
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_103_listener() { return ctx.changeTab("runs"); });
2160
+ i0.ɵɵelement(104, "i", 39);
2161
+ i0.ɵɵtext(105, " Test Runs ");
2162
+ i0.ɵɵtemplate(106, TestSuiteRunFormComponentExtended_span_106_Template, 2, 1, "span", 46);
497
2163
  i0.ɵɵelementEnd();
498
- i0.ɵɵelementStart(89, "button", 34);
499
- i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_89_listener() { return ctx.changeTab("details"); });
500
- i0.ɵɵelement(90, "i", 37);
501
- i0.ɵɵelementStart(91, "span");
502
- i0.ɵɵtext(92, "Details");
2164
+ i0.ɵɵelementStart(107, "button", 44);
2165
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_107_listener() { return ctx.changeTab("details"); });
2166
+ i0.ɵɵelement(108, "i", 47);
2167
+ i0.ɵɵtext(109, " Details ");
2168
+ i0.ɵɵelementEnd();
2169
+ i0.ɵɵelementStart(110, "button", 48);
2170
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_110_listener() { return ctx.changeTab("analytics"); });
2171
+ i0.ɵɵelement(111, "i", 49);
2172
+ i0.ɵɵtext(112, " Analytics ");
2173
+ i0.ɵɵelementEnd();
2174
+ i0.ɵɵelementStart(113, "button", 50);
2175
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_113_listener() { return ctx.changeTab("execution"); });
2176
+ i0.ɵɵelement(114, "i", 51);
2177
+ i0.ɵɵelementStart(115, "span");
2178
+ i0.ɵɵtext(116, "Execution");
503
2179
  i0.ɵɵelementEnd()()()();
504
- i0.ɵɵelementStart(93, "div", 38);
505
- i0.ɵɵtemplate(94, TestSuiteRunFormComponentExtended_div_94_Template, 11, 9, "div", 39)(95, TestSuiteRunFormComponentExtended_div_95_Template, 3, 2, "div", 40)(96, TestSuiteRunFormComponentExtended_div_96_Template, 42, 8, "div", 41);
506
- i0.ɵɵelementEnd()();
2180
+ i0.ɵɵelementStart(117, "div", 52);
2181
+ i0.ɵɵtemplate(118, TestSuiteRunFormComponentExtended_div_118_Template, 22, 16, "div", 53)(119, TestSuiteRunFormComponentExtended_div_119_Template, 6, 5, "div", 54)(120, TestSuiteRunFormComponentExtended_div_120_Template, 60, 18, "div", 55)(121, TestSuiteRunFormComponentExtended_div_121_Template, 5, 4, "div", 56)(122, TestSuiteRunFormComponentExtended_div_122_Template, 2, 5, "div", 57);
2182
+ i0.ɵɵelementEnd();
2183
+ i0.ɵɵelementStart(123, "button", 58);
2184
+ i0.ɵɵlistener("click", function TestSuiteRunFormComponentExtended_Template_button_click_123_listener() { return ctx.toggleShortcuts(); });
2185
+ i0.ɵɵelement(124, "i", 59);
2186
+ i0.ɵɵelementEnd();
2187
+ i0.ɵɵtemplate(125, TestSuiteRunFormComponentExtended_div_125_Template, 34, 0, "div", 60);
2188
+ i0.ɵɵelementEnd();
507
2189
  } if (rf & 2) {
508
2190
  i0.ɵɵadvance(2);
509
2191
  i0.ɵɵproperty("ngIf", ctx.testSuite);
510
2192
  i0.ɵɵadvance(3);
511
2193
  i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
512
- i0.ɵɵadvance(6);
513
- i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
2194
+ i0.ɵɵadvance();
2195
+ i0.ɵɵproperty("ngClass", ctx.getStatusIcon());
2196
+ i0.ɵɵadvance(5);
2197
+ i0.ɵɵproperty("ngClass", ctx.getStatusClass());
514
2198
  i0.ɵɵadvance();
515
2199
  i0.ɵɵproperty("ngClass", ctx.getStatusIcon());
516
2200
  i0.ɵɵadvance();
@@ -519,41 +2203,68 @@ let TestSuiteRunFormComponentExtended = class TestSuiteRunFormComponentExtended
519
2203
  i0.ɵɵproperty("ngIf", ctx.record.Environment);
520
2204
  i0.ɵɵadvance();
521
2205
  i0.ɵɵproperty("ngIf", ctx.record.TriggerType);
522
- i0.ɵɵadvance(9);
523
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(25, 29, ctx.record.StartedAt, "short"));
524
- i0.ɵɵadvance(6);
525
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(31, 32, ctx.record.CompletedAt, "short"));
526
- i0.ɵɵadvance(6);
2206
+ i0.ɵɵadvance(3);
2207
+ i0.ɵɵproperty("ngIf", ctx.record.SuiteID);
2208
+ i0.ɵɵadvance();
2209
+ i0.ɵɵproperty("disabled", ctx.isRefreshing);
2210
+ i0.ɵɵadvance();
2211
+ i0.ɵɵproperty("ngClass", ctx.isRefreshing ? "fa-sync fa-spin" : "fa-sync");
2212
+ i0.ɵɵadvance();
2213
+ i0.ɵɵtextInterpolate1(" ", ctx.isRefreshing ? "Refreshing..." : "Refresh", " ");
2214
+ i0.ɵɵadvance(7);
527
2215
  i0.ɵɵtextInterpolate(ctx.calculateDuration());
528
- i0.ɵɵadvance(5);
2216
+ i0.ɵɵadvance(8);
529
2217
  i0.ɵɵtextInterpolate1("", ctx.getPassRate().toFixed(1), "%");
530
- i0.ɵɵadvance(5);
2218
+ i0.ɵɵadvance(8);
531
2219
  i0.ɵɵtextInterpolate(ctx.formatCost(ctx.record.TotalCostUSD));
532
- i0.ɵɵadvance(5);
2220
+ i0.ɵɵadvance(8);
2221
+ i0.ɵɵtextInterpolate(ctx.getRelativeTime(ctx.record.StartedAt));
2222
+ i0.ɵɵadvance(9);
533
2223
  i0.ɵɵtextInterpolate(ctx.record.PassedTests || 0);
534
- i0.ɵɵadvance(6);
2224
+ i0.ɵɵadvance(8);
535
2225
  i0.ɵɵtextInterpolate(ctx.record.FailedTests || 0);
536
- i0.ɵɵadvance(6);
537
- i0.ɵɵtextInterpolate(ctx.record.SkippedTests || 0);
538
- i0.ɵɵadvance(6);
2226
+ i0.ɵɵadvance(8);
539
2227
  i0.ɵɵtextInterpolate(ctx.record.ErrorTests || 0);
540
- i0.ɵɵadvance(6);
2228
+ i0.ɵɵadvance(8);
2229
+ i0.ɵɵtextInterpolate(ctx.record.SkippedTests || 0);
2230
+ i0.ɵɵadvance(8);
541
2231
  i0.ɵɵtextInterpolate(ctx.record.TotalTests || 0);
542
- i0.ɵɵadvance(5);
2232
+ i0.ɵɵadvance(3);
2233
+ i0.ɵɵproperty("ngIf", !ctx.editingTags);
2234
+ i0.ɵɵadvance();
2235
+ i0.ɵɵproperty("ngIf", ctx.editingTags);
2236
+ i0.ɵɵadvance(3);
543
2237
  i0.ɵɵclassProp("active", ctx.activeTab === "overview");
544
- i0.ɵɵadvance(4);
2238
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "overview");
2239
+ i0.ɵɵadvance(3);
545
2240
  i0.ɵɵclassProp("active", ctx.activeTab === "runs");
546
- i0.ɵɵadvance(4);
2241
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "runs");
2242
+ i0.ɵɵadvance(3);
547
2243
  i0.ɵɵproperty("ngIf", ctx.testRunsLoaded);
548
2244
  i0.ɵɵadvance();
549
2245
  i0.ɵɵclassProp("active", ctx.activeTab === "details");
2246
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "details");
2247
+ i0.ɵɵadvance(3);
2248
+ i0.ɵɵclassProp("active", ctx.activeTab === "analytics");
2249
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "analytics");
2250
+ i0.ɵɵadvance(3);
2251
+ i0.ɵɵclassProp("active", ctx.activeTab === "execution");
2252
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "execution");
550
2253
  i0.ɵɵadvance(5);
551
2254
  i0.ɵɵproperty("ngIf", ctx.activeTab === "overview");
552
2255
  i0.ɵɵadvance();
553
2256
  i0.ɵɵproperty("ngIf", ctx.activeTab === "runs");
554
2257
  i0.ɵɵadvance();
555
2258
  i0.ɵɵproperty("ngIf", ctx.activeTab === "details");
556
- } }, dependencies: [i3.NgClass, i3.NgForOf, i3.NgIf, i4.ButtonComponent, i3.DatePipe], styles: [".test-suite-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n\n\n.suite-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.suite-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.suite-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.suite-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.environment[_ngcontent-%COMP%], \n.trigger[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #666;\n padding: 4px 8px;\n background: #f0f0f0;\n border-radius: 6px;\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.results-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 8px;\n background: #f8f9fa;\n}\n\n.result-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n}\n\n.result-item[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n}\n\n.result-item[_ngcontent-%COMP%] .label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: #666;\n}\n\n.result-item.passed[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.result-item.passed[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n color: #4caf50;\n}\n\n.result-item.failed[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.result-item.failed[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n color: #f44336;\n}\n\n.result-item.skipped[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.result-item.skipped[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n color: #9e9e9e;\n}\n\n.result-item.error[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.result-item.error[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n color: #ff9800;\n}\n\n.result-item.total[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.result-item.total[_ngcontent-%COMP%] .count[_ngcontent-%COMP%] {\n color: #2196f3;\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-stats[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n}\n\n.result-counts[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #999;\n}\n\n\n\n.test-runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: white;\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: #e3f2fd;\n border-color: #90caf9;\n}\n\n.run-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #f0f0f0;\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: #666;\n flex-shrink: 0;\n}\n\n.run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.run-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: #666;\n}\n\n.run-meta[_ngcontent-%COMP%] .status[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.test-run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: #999;\n font-size: 14px;\n}\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\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\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 background: white;\n border-radius: 12px;\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 .results-summary[_ngcontent-%COMP%] {\n flex-wrap: wrap;\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 }); }
2259
+ i0.ɵɵadvance();
2260
+ i0.ɵɵproperty("ngIf", ctx.activeTab === "analytics");
2261
+ i0.ɵɵadvance();
2262
+ i0.ɵɵproperty("ngIf", ctx.activeTab === "execution");
2263
+ i0.ɵɵadvance();
2264
+ i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
2265
+ i0.ɵɵadvance(2);
2266
+ i0.ɵɵproperty("ngIf", ctx.showShortcuts);
2267
+ } }, dependencies: [i4.NgClass, i4.NgForOf, i4.NgIf, i5.DefaultValueAccessor, i5.RadioControlValueAccessor, i5.NgControlStatus, i5.NgModel, i6.DialogContainerDirective, i7.ButtonComponent, i3.EvaluationBadgeComponent, i3.EvaluationModeToggleComponent, i3.ExecutionContextComponent, i8.EntityLinkPillComponent, i4.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --suite-run-primary: #3b82f6;\n --suite-run-primary-light: #eff6ff;\n --suite-run-success: #10b981;\n --suite-run-success-light: #ecfdf5;\n --suite-run-danger: #ef4444;\n --suite-run-danger-light: #fef2f2;\n --suite-run-warning: #f59e0b;\n --suite-run-warning-light: #fffbeb;\n --suite-run-info: #8b5cf6;\n --suite-run-info-light: #f5f3ff;\n --suite-run-neutral: #6b7280;\n --suite-run-neutral-light: #f9fafb;\n --suite-run-bg: #f8fafc;\n --suite-run-card: #ffffff;\n --suite-run-border: #e2e8f0;\n --suite-run-text: #1e293b;\n --suite-run-text-secondary: #64748b;\n --suite-run-radius: 12px;\n --suite-run-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);\n --suite-run-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --suite-run-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n.test-suite-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--suite-run-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n\n\n\n\n.suite-run-header[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n padding: 20px 24px;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n text-decoration: none;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: var(--suite-run-transition);\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n color: #2563eb;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #cbd5e1;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--suite-run-text);\n font-weight: 500;\n}\n\n\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n}\n\n.suite-run-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--suite-run-radius);\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(--suite-run-shadow);\n}\n\n.suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.suite-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-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 text-transform: uppercase;\n letter-spacing: 0.025em;\n}\n\n.status-badge.status-completed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-badge.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-badge.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-badge.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-badge.status-cancelled[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.meta-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--suite-run-neutral-light);\n border-radius: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.meta-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 20px;\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(--suite-run-border);\n border-radius: 10px;\n padding: 14px;\n transition: var(--suite-run-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\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(--suite-run-card);\n border-radius: 10px;\n color: var(--suite-run-primary);\n font-size: 16px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\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: var(--suite-run-text-secondary);\n margin-top: 2px;\n}\n\n\n\n\n\n.results-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding-top: 20px;\n border-top: 1px solid var(--suite-run-border);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n flex-shrink: 0;\n transition: var(--suite-run-transition);\n}\n\n.result-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.result-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.result-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-item.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.passed[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.result-item.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.failed[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.result-item.error[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.error[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.result-item.skipped[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.skipped[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n.result-item.total[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.total[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 24px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: 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: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--suite-run-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n border-bottom-color: var(--suite-run-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(--suite-run-border);\n color: var(--suite-run-text-secondary);\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: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n width: 18px;\n height: 18px;\n background: var(--suite-run-neutral-light);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n max-width: 800px;\n margin: 0 auto;\n width: 100%;\n}\n\n.result-hero[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 48px 32px;\n text-align: center;\n border: 2px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border-color: var(--suite-run-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);\n border-color: var(--suite-run-danger);\n}\n\n.result-hero.running[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-color: var(--suite-run-primary);\n}\n\n.result-hero.pending[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f5f3ff 0%, #ede9fe 100%);\n border-color: var(--suite-run-info);\n}\n\n.result-hero-icon[_ngcontent-%COMP%] {\n font-size: 72px;\n margin-bottom: 20px;\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.result-hero.running[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.result-hero.pending[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-info);\n}\n\n.result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 32px;\n font-weight: 800;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.result-hero-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 32px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-divider[_ngcontent-%COMP%] {\n width: 1px;\n height: 40px;\n background: var(--suite-run-border);\n}\n\n\n\n.progress-section[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n border: 1px solid rgba(59, 130, 246, 0.2);\n border-radius: var(--suite-run-radius);\n padding: 20px;\n text-align: center;\n}\n\n.progress-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 500;\n color: var(--suite-run-primary);\n margin-bottom: 8px;\n}\n\n.progress-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n}\n\n.auto-refresh-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n\n\n\n\n.runs-tab[_ngcontent-%COMP%] {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\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: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 1px solid var(--suite-run-border);\n}\n\n.skeleton-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 50%;\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 8px;\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 background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 4px;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] {\n width: 70%;\n}\n\n.skeleton-line.narrow[_ngcontent-%COMP%] {\n width: 40%;\n}\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n.test-runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n border-color: #93c5fd;\n transform: translateX(4px);\n}\n\n.test-run-item[_ngcontent-%COMP%]:active {\n transform: translateX(2px);\n}\n\n.run-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n color: white;\n font-size: 16px;\n flex-shrink: 0;\n box-shadow: var(--suite-run-shadow);\n}\n\n.run-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.run-score[_ngcontent-%COMP%], \n.run-duration[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.run-duration[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.test-run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: #cbd5e1;\n font-size: 14px;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n transform: translateX(4px);\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 20px;\n text-align: center;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 2px dashed var(--suite-run-border);\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(--suite-run-neutral-light);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: #cbd5e1;\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--suite-run-text-secondary);\n max-width: 300px;\n}\n\n\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n.details-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 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: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--suite-run-text);\n word-wrap: break-word;\n}\n\n.detail-value.monospace[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n background: var(--suite-run-neutral-light);\n padding: 6px 10px;\n border-radius: 6px;\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n text-decoration: none;\n font-weight: 500;\n transition: var(--suite-run-transition);\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n color: #2563eb;\n text-decoration: underline;\n}\n\n.status-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-inline.status-completed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-inline.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-inline.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-inline.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-inline.status-cancelled[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n\n\n\n\n\n\n.shortcuts-toggle[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n box-shadow: var(--suite-run-shadow);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--suite-run-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n padding: 12px 16px;\n box-shadow: var(--suite-run-shadow-lg);\n font-size: 12px;\n z-index: 100;\n opacity: 0.9;\n transition: var(--suite-run-transition);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.shortcuts-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--suite-run-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--suite-run-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--suite-run-text);\n background: var(--suite-run-border);\n}\n\n.shortcut-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-child {\n color: var(--suite-run-text-secondary);\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\nkbd[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%);\n border: 1px solid #cbd5e1;\n border-radius: 4px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text);\n box-shadow: 0 1px 0 #94a3b8;\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .result-hero-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .stat-divider[_ngcontent-%COMP%] {\n display: none;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 16px;\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 .suite-run-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 20px;\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: 8px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n flex-direction: column;\n text-align: center;\n gap: 8px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .results-summary[_ngcontent-%COMP%] {\n gap: 8px;\n padding-top: 16px;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 8px;\n margin-bottom: -8px;\n }\n\n .result-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n min-width: 90px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .result-count[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 16px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 14px 16px;\n font-size: 13px;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 32px 20px;\n }\n\n .result-hero-icon[_ngcontent-%COMP%] {\n font-size: 56px;\n }\n\n .result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n .stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-sequence[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n\n .run-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .run-name[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .run-meta[_ngcontent-%COMP%] {\n gap: 10px;\n font-size: 11px;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 40px 16px;\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 .details-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n gap: 16px;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-bottom: 12px;\n }\n\n .suite-run-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n font-size: 18px;\n }\n\n .suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .suite-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 .meta-tag[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 8px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 10px;\n gap: 6px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 14px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .result-item[_ngcontent-%COMP%] {\n padding: 8px 10px;\n min-width: 80px;\n gap: 8px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .result-count[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .result-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 24px 16px;\n }\n\n .result-hero-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 20px;\n margin-bottom: 12px;\n }\n\n .stat-value[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .progress-section[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .progress-info[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n padding: 12px;\n gap: 10px;\n }\n\n .run-sequence[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n font-size: 11px;\n }\n\n .run-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 12px;\n border-radius: 8px;\n }\n\n .run-name[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-bottom: 3px;\n }\n\n .run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n font-size: 10px;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 32px 12px;\n }\n\n .empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .details-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 14px;\n margin-bottom: 16px;\n }\n\n .detail-label[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .detail-value[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .test-run-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n\n .test-run-item[_ngcontent-%COMP%]:hover {\n transform: none;\n background: var(--suite-run-card);\n border-color: var(--suite-run-border);\n }\n\n .test-run-item[_ngcontent-%COMP%]:active {\n background: var(--suite-run-primary-light);\n border-color: #93c5fd;\n }\n\n .tab[_ngcontent-%COMP%]:hover {\n background: transparent;\n color: var(--suite-run-text-secondary);\n }\n\n .tab[_ngcontent-%COMP%]:active {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n }\n\n .metric-card[_ngcontent-%COMP%]:hover {\n transform: none;\n box-shadow: none;\n }\n\n .result-item[_ngcontent-%COMP%]:hover {\n transform: none;\n box-shadow: none;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media print {\n .suite-run-header[_ngcontent-%COMP%] {\n background: white;\n box-shadow: none;\n border-bottom: 2px solid #000;\n }\n\n .tabs-container[_ngcontent-%COMP%], \n .header-actions[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 20px 0;\n }\n\n .result-hero[_ngcontent-%COMP%], \n .test-run-item[_ngcontent-%COMP%], \n .details-card[_ngcontent-%COMP%] {\n box-shadow: none;\n border: 1px solid #ccc;\n }\n}\n\n\n\n\n\n@media (prefers-color-scheme: dark) {\n \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(59, 130, 246, 0.04) 0%, rgba(59, 130, 246, 0.08) 100%);\n border: 1px solid rgba(59, 130, 246, 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(--suite-run-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: var(--suite-run-primary-light);\n color: var(--suite-run-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(--suite-run-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(--suite-run-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%]:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\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(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 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: var(--suite-run-primary-light);\n border-bottom: 1px solid rgba(59, 130, 246, 0.2);\n}\n\n.tags-editor-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-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(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n color: var(--suite-run-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(--suite-run-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--suite-run-transition);\n}\n\n.tag-remove-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.tags-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-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(--suite-run-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--suite-run-neutral-light);\n}\n\n.tag-text-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n background: var(--suite-run-card);\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n.tag-text-input[_ngcontent-%COMP%]::placeholder {\n color: var(--suite-run-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(--suite-run-neutral-light);\n border-top: 1px solid var(--suite-run-border);\n}\n\n\n\n\n\n.runs-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.run-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--suite-run-border);\n background: var(--suite-run-card);\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n color: white;\n}\n\n.filter-btn.passed[_ngcontent-%COMP%]:hover, \n.filter-btn.passed.active[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n border-color: var(--suite-run-success);\n color: white;\n}\n\n.filter-btn.failed[_ngcontent-%COMP%]:hover, \n.filter-btn.failed.active[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n border-color: var(--suite-run-danger);\n color: white;\n}\n\n.filter-btn.error[_ngcontent-%COMP%]:hover, \n.filter-btn.error.active[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n border-color: var(--suite-run-warning);\n color: white;\n}\n\n.runs-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n\n\n.test-run-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n margin-bottom: 10px;\n}\n\n.test-run-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.run-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-feedback-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.run-feedback-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 6px;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 500;\n}\n\n.tag-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border: 1px solid #bfdbfe;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: #1d4ed8;\n}\n\n.run-expand[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover .run-expand[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.run-cost[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-cost[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n\n\n\n\n.inline-feedback[_ngcontent-%COMP%] {\n padding: 0 16px 16px;\n animation: _ngcontent-%COMP%_slideDown 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.feedback-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--suite-run-border);\n margin-bottom: 16px;\n}\n\n.feedback-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.inline-rating[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.rating-numbers[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.rating-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: 2px solid var(--suite-run-border);\n border-radius: 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.rating-btn[_ngcontent-%COMP%]:hover, \n.rating-btn.hover[_ngcontent-%COMP%] {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.rating-btn.low[_ngcontent-%COMP%]:hover, \n.rating-btn.low.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.rating-btn.mid[_ngcontent-%COMP%]:hover, \n.rating-btn.mid.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.rating-btn.high[_ngcontent-%COMP%]:hover, \n.rating-btn.high.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.rating-btn.selected[_ngcontent-%COMP%] {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.rating-btn.selected.low[_ngcontent-%COMP%] {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger);\n color: white;\n}\n\n.rating-btn.selected.mid[_ngcontent-%COMP%] {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning);\n color: white;\n}\n\n.rating-btn.selected.high[_ngcontent-%COMP%] {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success);\n color: white;\n}\n\n.rating-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--suite-run-neutral-light);\n border-radius: 8px;\n}\n\n.rating-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.rating-label-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.correctness-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.correctness-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.correctness-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n}\n\n.radio-opt[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.radio-opt[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.comments-row[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.feedback-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n}\n\n.feedback-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n\n.feedback-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding-top: 8px;\n}\n\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\n .runs-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .run-filters[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .runs-actions[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .rating-numbers[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .rating-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 12px;\n }\n\n .correctness-row[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .feedback-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .feedback-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n }\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.result-hero.running[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%], \n.runs-tab[_ngcontent-%COMP%], \n.details-tab[_ngcontent-%COMP%], \n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.analytics-section[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.analytics-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.analytics-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.analytics-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.legend-item.passed[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.legend-item.failed[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.legend-item.error[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.legend-item.skipped[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n\n\n.performance-matrix[_ngcontent-%COMP%] {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.matrix-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 120px 150px 100px 100px;\n border-bottom: 1px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n cursor: pointer;\n}\n\n.matrix-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.matrix-row[_ngcontent-%COMP%]:hover:not(.matrix-header-row) {\n background: var(--suite-run-primary-light);\n}\n\n.matrix-row.passed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.matrix-row.failed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.matrix-row.error[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.matrix-row.skipped[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n.matrix-header-row[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n cursor: default;\n}\n\n.matrix-cell[_ngcontent-%COMP%] {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n gap: 12px;\n}\n\n.test-sequence[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.status-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-indicator.status-passed[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.status-indicator.status-failed[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.status-indicator.status-error[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.status-indicator.status-skipped[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n.status-indicator.status-pending[_ngcontent-%COMP%] {\n color: var(--suite-run-info);\n}\n\n.status-indicator.status-running[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.score-bar[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 20px;\n background: var(--suite-run-neutral-light);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.score-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 10px;\n transition: width 0.3s ease;\n}\n\n.score-fill.high[_ngcontent-%COMP%] {\n background: linear-gradient(90deg, var(--suite-run-success) 0%, #34d399 100%);\n}\n\n.score-fill.medium[_ngcontent-%COMP%] {\n background: linear-gradient(90deg, var(--suite-run-warning) 0%, #fbbf24 100%);\n}\n\n.score-fill.low[_ngcontent-%COMP%] {\n background: linear-gradient(90deg, var(--suite-run-danger) 0%, #f87171 100%);\n}\n\n.score-text[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.na-value[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.stat-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--suite-run-border);\n border-radius: 12px;\n transition: var(--suite-run-transition);\n}\n\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n font-size: 20px;\n}\n\n.stat-icon.passed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.stat-icon.failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.stat-icon.score[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.stat-icon.duration[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.stat-icon.cost[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.stat-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-percent[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n\n\n@media (max-width: 768px) {\n .analytics-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .matrix-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 8px;\n padding: 12px;\n }\n\n .matrix-header-row[_ngcontent-%COMP%] {\n display: none;\n }\n\n .matrix-cell[_ngcontent-%COMP%] {\n padding: 4px 0;\n }\n\n .test-name-cell[_ngcontent-%COMP%]::before, \n .status-cell[_ngcontent-%COMP%]::before, \n .score-cell[_ngcontent-%COMP%]::before, \n .duration-cell[_ngcontent-%COMP%]::before, \n .cost-cell[_ngcontent-%COMP%]::before {\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n margin-right: 8px;\n min-width: 80px;\n }\n\n .status-cell[_ngcontent-%COMP%]::before { content: 'Status:'; }\n .score-cell[_ngcontent-%COMP%]::before { content: 'Score:'; }\n .duration-cell[_ngcontent-%COMP%]::before { content: 'Duration:'; }\n .cost-cell[_ngcontent-%COMP%]::before { content: 'Cost:'; }\n\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .stat-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n}\n\n\n\n.tab[_ngcontent-%COMP%]:focus-visible, \n.test-run-item[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--suite-run-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n.analytics-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--suite-run-text-secondary);\n}\n\n.analytics-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--suite-run-primary);\n}\n\n\n\n\n\n.results-table-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.results-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.results-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n}\n\n.results-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.results-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid #f1f5f9;\n vertical-align: middle;\n}\n\n.results-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n\n\n.seq-col[_ngcontent-%COMP%] {\n width: 40px;\n min-width: 40px;\n text-align: center;\n white-space: nowrap;\n}\n\n.name-col[_ngcontent-%COMP%] {\n \n\n width: auto;\n max-width: 50%;\n}\n\n.status-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n}\n\n.score-col[_ngcontent-%COMP%] {\n width: 1%; \n\n min-width: 120px; \n\n white-space: nowrap;\n}\n\n.duration-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: right;\n}\n\n.cost-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: right;\n}\n\n\n\n.result-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.result-row[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.result-row.row-passed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.result-row.row-failed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.result-row.row-error[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.result-row.row-skipped[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n\n\n.test-name-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.test-name-wrapper[_ngcontent-%COMP%] .test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.test-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n\n\n.score-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] {\n flex: 1;\n height: 6px;\n background: var(--suite-run-neutral-light);\n border-radius: 3px;\n overflow: hidden;\n min-width: 60px;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.medium[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n}\n\n.score-display[_ngcontent-%COMP%] .score-text[_ngcontent-%COMP%] {\n position: static;\n transform: none;\n font-size: 12px;\n font-weight: 600;\n color: var(--suite-run-text);\n min-width: 35px;\n text-align: right;\n}\n\n\n\n.results-table[_ngcontent-%COMP%] .status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-passed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-error[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-skipped[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n\n\n@media (max-width: 768px) {\n .results-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n }\n\n .results-table[_ngcontent-%COMP%] {\n min-width: 600px;\n }\n\n .results-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .results-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .name-col[_ngcontent-%COMP%] {\n min-width: 150px;\n }\n}\n\n\n\n\n\n@media (prefers-contrast: high) {\n .status-badge[_ngcontent-%COMP%], \n .status-inline[_ngcontent-%COMP%] {\n border: 2px solid currentColor;\n }\n\n .test-run-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.evaluation-summary[_ngcontent-%COMP%] {\n margin-top: 20px;\n}\n\n.eval-summary-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 16px;\n}\n\n.eval-summary-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n}\n\n.eval-summary-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.eval-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-bottom: 1px solid var(--suite-run-border);\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-card-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.eval-card-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.eval-stat-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.eval-stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.eval-stat-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-stat-value.correct[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.eval-stat-value.incorrect[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n font-weight: 500;\n font-size: 12px;\n}\n\n.eval-stat-value.error[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.eval-stat-value.timeout[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.eval-card-footer[_ngcontent-%COMP%] {\n padding: 10px 16px;\n background: var(--suite-run-warning-light);\n border-top: 1px solid rgba(245, 158, 11, 0.2);\n}\n\n.pending-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-warning);\n}\n\n.pending-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n\n\n\n\n.needs-review-section[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n}\n\n.needs-review-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 20px;\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-bottom: 1px solid rgba(245, 158, 11, 0.3);\n}\n\n.needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #92400e;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.review-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: #92400e;\n background: rgba(255, 255, 255, 0.6);\n padding: 2px 10px;\n border-radius: 12px;\n}\n\n.needs-review-list[_ngcontent-%COMP%] {\n padding: 8px;\n}\n\n.review-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 8px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.review-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.review-item-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.review-item.high-priority[_ngcontent-%COMP%] .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.review-item.medium-priority[_ngcontent-%COMP%] .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.review-item[_ngcontent-%COMP%]:not(.high-priority):not(.medium-priority) .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.review-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.review-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.review-item-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--suite-run-text-secondary);\n}\n\n.review-item-action[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n font-size: 12px;\n}\n\n.review-item[_ngcontent-%COMP%]:hover .review-item-action[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.review-more[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--suite-run-border);\n}\n\n\n\n@media (max-width: 768px) {\n .eval-summary-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .eval-card-header[_ngcontent-%COMP%] {\n padding: 10px 14px;\n font-size: 12px;\n }\n\n .eval-card-body[_ngcontent-%COMP%] {\n padding: 12px 14px;\n }\n\n .needs-review-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .review-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .review-item-icon[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n.feedback-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: center;\n}\n\n.feedback-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--suite-run-neutral-light);\n}\n\n.feedback-rating.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.feedback-rating.mid[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.feedback-rating.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i.correct[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i.incorrect[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.na-value.needs-review[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n opacity: 0.7;\n}\n\n.na-value.needs-review[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}"], changeDetection: 0 }); }
557
2268
  };
558
2269
  TestSuiteRunFormComponentExtended = __decorate([
559
2270
  RegisterClass(BaseFormComponent, 'MJ: Test Suite Runs')
@@ -561,9 +2272,12 @@ TestSuiteRunFormComponentExtended = __decorate([
561
2272
  export { TestSuiteRunFormComponentExtended };
562
2273
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestSuiteRunFormComponentExtended, [{
563
2274
  type: Component,
564
- args: [{ selector: 'mj-test-suite-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-run-form\">\n <!-- Header Section -->\n <div class=\"suite-run-header\">\n <div class=\"breadcrumb\" *ngIf=\"testSuite\">\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\">\n <i class=\"fas fa-folder\"></i> {{ testSuite.Name }}\n </a>\n <i class=\"fas fa-chevron-right\"></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=\"suite-run-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-run-info\">\n <h1>Test Suite Run</h1>\n <div class=\"suite-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=\"environment\" *ngIf=\"record.Environment\">{{ record.Environment }}</span>\n <span class=\"trigger\" *ngIf=\"record.TriggerType\">{{ record.TriggerType }}</span>\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\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\">Pass Rate</div>\n <div class=\"metric-value\">{{ getPassRate().toFixed(1) }}%</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Cost</div>\n <div class=\"metric-value\">{{ formatCost(record.TotalCostUSD) }}</div>\n </div>\n </div>\n\n <!-- Test Results Summary -->\n <div class=\"results-summary\">\n <div class=\"result-item passed\">\n <i class=\"fas fa-check-circle\"></i>\n <span class=\"count\">{{ record.PassedTests || 0 }}</span>\n <span class=\"label\">Passed</span>\n </div>\n <div class=\"result-item failed\">\n <i class=\"fas fa-times-circle\"></i>\n <span class=\"count\">{{ record.FailedTests || 0 }}</span>\n <span class=\"label\">Failed</span>\n </div>\n <div class=\"result-item skipped\">\n <i class=\"fas fa-forward\"></i>\n <span class=\"count\">{{ record.SkippedTests || 0 }}</span>\n <span class=\"label\">Skipped</span>\n </div>\n <div class=\"result-item error\">\n <i class=\"fas fa-exclamation-circle\"></i>\n <span class=\"count\">{{ record.ErrorTests || 0 }}</span>\n <span class=\"label\">Errors</span>\n </div>\n <div class=\"result-item total\">\n <i class=\"fas fa-list\"></i>\n <span class=\"count\">{{ record.TotalTests || 0 }}</span>\n <span class=\"label\">Total</span>\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 === 'runs'\" (click)=\"changeTab('runs')\">\n <i class=\"fas fa-list\"></i>\n <span>Test Runs</span>\n <span class=\"tab-badge\" *ngIf=\"testRunsLoaded\">{{ testRuns.length }}</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'details'\" (click)=\"changeTab('details')\">\n <i class=\"fas fa-info-circle\"></i>\n <span>Details</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 === 'Completed' && getPassRate() >= 90\" [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>SUITE {{ record.Status.toUpperCase() }}</h2>\n <div class=\"result-stats\">Pass Rate: {{ getPassRate().toFixed(1) }}%</div>\n <div class=\"result-counts\">{{ record.PassedTests }} of {{ record.TotalTests }} tests passed</div>\n </div>\n </div>\n </div>\n\n <!-- Test Runs Tab -->\n <div class=\"runs-tab\" *ngIf=\"activeTab === 'runs'\">\n <div class=\"test-runs-list\" *ngIf=\"testRuns.length > 0\">\n <div class=\"test-run-item\" *ngFor=\"let run of testRuns\" (click)=\"openTestRun(run.ID)\">\n <div class=\"run-sequence\">{{ run.Sequence }}</div>\n <div class=\"run-icon\" [style.background-color]=\"run.Status === 'Passed' ? '#4caf50' : run.Status === 'Failed' ? '#f44336' : '#ff9800'\">\n <i class=\"fas\" [class.fa-check]=\"run.Status === 'Passed'\" [class.fa-times]=\"run.Status === 'Failed'\" [class.fa-exclamation]=\"run.Status === 'Error'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-name\">{{ run.Test }}</div>\n <div class=\"run-meta\">\n <span class=\"status\" [style.color]=\"run.Status === 'Passed' ? '#4caf50' : run.Status === 'Failed' ? '#f44336' : '#ff9800'\">{{ run.Status }}</span>\n <span *ngIf=\"run.Score != null\">Score: {{ run.Score.toFixed(4) }}</span>\n <span *ngIf=\"run.DurationSeconds\">{{ run.DurationSeconds.toFixed(1) }}s</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <div class=\"no-data\" *ngIf=\"testRunsLoaded && testRuns.length === 0\">\n <i class=\"fas fa-inbox\"></i>\n <p>No test runs found for this suite execution</p>\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\">Run ID</div>\n <div class=\"detail-value\">{{ record.ID }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Test Suite</div>\n <div class=\"detail-value\">\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\" *ngIf=\"testSuite\">{{ testSuite.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\">Run By</div>\n <div class=\"detail-value\">{{ record.RunByUser }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Environment</div>\n <div class=\"detail-value\">{{ record.Environment || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Trigger Type</div>\n <div class=\"detail-value\">{{ record.TriggerType || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Git Commit</div>\n <div class=\"detail-value\">{{ record.GitCommit || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Agent Version</div>\n <div class=\"detail-value\">{{ record.AgentVersion || 'N/A' }}</div>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [".test-suite-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n/* Header */\n.suite-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.suite-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.suite-run-info h1 {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 600;\n color: #333;\n}\n\n.suite-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.environment,\n.trigger {\n font-size: 13px;\n color: #666;\n padding: 4px 8px;\n background: #f0f0f0;\n border-radius: 6px;\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.results-summary {\n display: flex;\n gap: 16px;\n padding-top: 16px;\n border-top: 1px solid #e0e0e0;\n}\n\n.result-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-radius: 8px;\n background: #f8f9fa;\n}\n\n.result-item i {\n font-size: 20px;\n}\n\n.result-item .count {\n font-size: 20px;\n font-weight: 700;\n}\n\n.result-item .label {\n font-size: 12px;\n font-weight: 500;\n color: #666;\n}\n\n.result-item.passed i,\n.result-item.passed .count {\n color: #4caf50;\n}\n\n.result-item.failed i,\n.result-item.failed .count {\n color: #f44336;\n}\n\n.result-item.skipped i,\n.result-item.skipped .count {\n color: #9e9e9e;\n}\n\n.result-item.error i,\n.result-item.error .count {\n color: #ff9800;\n}\n\n.result-item.total i,\n.result-item.total .count {\n color: #2196f3;\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-stats {\n font-size: 20px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n}\n\n.result-counts {\n font-size: 16px;\n color: #999;\n}\n\n/* Test Runs Tab */\n.test-runs-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: white;\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.test-run-item:hover {\n background: #e3f2fd;\n border-color: #90caf9;\n}\n\n.run-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #f0f0f0;\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: #666;\n flex-shrink: 0;\n}\n\n.run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.run-content {\n flex: 1;\n}\n\n.run-name {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n}\n\n.run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: #666;\n}\n\n.run-meta .status {\n font-weight: 700;\n}\n\n.test-run-item > i {\n color: #999;\n font-size: 14px;\n}\n\n/* Details Tab */\n.details-tab {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\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/* 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 background: white;\n border-radius: 12px;\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 .results-summary {\n flex-wrap: wrap;\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"] }]
565
- }], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }], null); })();
566
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestSuiteRunFormComponentExtended, { className: "TestSuiteRunFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-run-form.component.ts", lineNumber: 19 }); })();
2275
+ args: [{ selector: 'mj-test-suite-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-run-form\" kendoDialogContainer>\n <!-- Header Section -->\n <div class=\"suite-run-header\">\n <!-- Breadcrumb -->\n <div class=\"breadcrumb\" *ngIf=\"testSuite\">\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\">\n <i class=\"fas fa-layer-group\"></i>\n {{ testSuite.Name }}\n </a>\n <i class=\"fas fa-chevron-right separator\"></i>\n <span class=\"current\">Run #{{ record.ID.substring(0, 8) }}</span>\n </div>\n\n <!-- Header Content -->\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-run-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"suite-run-info\">\n <h1>Suite Run</h1>\n <div class=\"suite-run-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n <span class=\"meta-tag environment\" *ngIf=\"record.Environment\">\n <i class=\"fas fa-server\"></i>\n {{ record.Environment }}\n </span>\n <span class=\"meta-tag trigger\" *ngIf=\"record.TriggerType\">\n <i class=\"fas fa-bolt\"></i>\n {{ record.TriggerType }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <!-- Evaluation Mode Toggle -->\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button kendoButton (click)=\"reRunSuite()\" themeColor=\"primary\" *ngIf=\"record.SuiteID\">\n <i class=\"fas fa-play\"></i> Re-run Suite\n </button>\n <button kendoButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : '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-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n <div class=\"metric-label\">Duration</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getPassRate().toFixed(1) }}%</div>\n <div class=\"metric-label\">Pass Rate</div>\n </div>\n </div>\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-value\">{{ formatCost(record.TotalCostUSD) }}</div>\n <div class=\"metric-label\">Total Cost</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-calendar\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getRelativeTime(record.StartedAt) }}</div>\n <div class=\"metric-label\">Started</div>\n </div>\n </div>\n </div>\n\n <!-- Results Summary -->\n <div class=\"results-summary\">\n <div class=\"result-item passed\">\n <div class=\"result-icon\">\n <i class=\"fas fa-check-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.PassedTests || 0 }}</span>\n <span class=\"result-label\">Passed</span>\n </div>\n </div>\n <div class=\"result-item failed\">\n <div class=\"result-icon\">\n <i class=\"fas fa-times-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.FailedTests || 0 }}</span>\n <span class=\"result-label\">Failed</span>\n </div>\n </div>\n <div class=\"result-item error\">\n <div class=\"result-icon\">\n <i class=\"fas fa-exclamation-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.ErrorTests || 0 }}</span>\n <span class=\"result-label\">Errors</span>\n </div>\n </div>\n <div class=\"result-item skipped\">\n <div class=\"result-icon\">\n <i class=\"fas fa-forward\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.SkippedTests || 0 }}</span>\n <span class=\"result-label\">Skipped</span>\n </div>\n </div>\n <div class=\"result-item total\">\n <div class=\"result-icon\">\n <i class=\"fas fa-list\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.TotalTests || 0 }}</span>\n <span class=\"result-label\">Total</span>\n </div>\n </div>\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\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-list\"></i> Test Runs\n <span class=\"tab-badge\" *ngIf=\"testRunsLoaded\">{{ testRuns.length }}</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'details'\"\n (click)=\"changeTab('details')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'details'\">\n <i class=\"fas fa-info-circle\"></i> Details\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'analytics'\"\n (click)=\"changeTab('analytics')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'analytics'\"\n title=\"Press 4\">\n <i class=\"fas fa-chart-bar\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'execution'\"\n (click)=\"changeTab('execution')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'execution'\"\n title=\"Press 5\">\n <i class=\"fas fa-microchip\"></i>\n <span>Execution</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\"\n [class.passed]=\"record.Status === 'Completed' && getPassRate() >= 90\"\n [class.failed]=\"record.Status === 'Failed' || getPassRate() < 50\"\n [class.running]=\"record.Status === 'Running'\"\n [class.pending]=\"record.Status === 'Pending'\">\n <div class=\"result-hero-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"result-hero-text\">\n <h2>SUITE {{ record.Status.toUpperCase() || 'UNKNOWN' }}</h2>\n <div class=\"result-hero-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ getPassRate().toFixed(1) }}%</span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n <div class=\"stat-divider\"></div>\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ record.PassedTests || 0 }} / {{ record.TotalTests || 0 }}</span>\n <span class=\"stat-label\">Tests Passed</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Evaluation Metrics Summary -->\n <div class=\"evaluation-summary\" *ngIf=\"evaluationMetrics && feedbacksLoaded\">\n <div class=\"eval-summary-grid\">\n <!-- Human Feedback Card -->\n <div class=\"eval-summary-card\" *ngIf=\"evalPreferences.showHuman\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-user\"></i>\n <span>Human Feedback</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Reviewed</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.humanReviewedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n <div class=\"eval-stat-row\" *ngIf=\"evaluationMetrics.humanReviewedCount > 0\">\n <span class=\"eval-stat-label\">Avg Rating</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.humanAvgRating.toFixed(1) }}/10</span>\n </div>\n <div class=\"eval-stat-row\" *ngIf=\"evaluationMetrics.humanReviewedCount > 0\">\n <span class=\"eval-stat-label\">Correct</span>\n <span class=\"eval-stat-value correct\">{{ evaluationMetrics.humanCorrectCount }}</span>\n <span class=\"eval-stat-value incorrect\" *ngIf=\"evaluationMetrics.humanIncorrectCount > 0\">{{ evaluationMetrics.humanIncorrectCount }} incorrect</span>\n </div>\n </div>\n <div class=\"eval-card-footer\" *ngIf=\"evaluationMetrics.humanPendingCount > 0\">\n <span class=\"pending-badge\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ evaluationMetrics.humanPendingCount }} need review\n </span>\n </div>\n </div>\n\n <!-- Auto Score Card -->\n <div class=\"eval-summary-card\" *ngIf=\"evalPreferences.showAuto\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>Auto Evaluation</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Evaluated</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.autoEvaluatedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n <div class=\"eval-stat-row\" *ngIf=\"evaluationMetrics.autoEvaluatedCount > 0\">\n <span class=\"eval-stat-label\">Avg Score</span>\n <span class=\"eval-stat-value\">{{ (evaluationMetrics.autoAvgScore * 100).toFixed(0) }}%</span>\n </div>\n <div class=\"eval-stat-row\" *ngIf=\"evaluationMetrics.autoEvaluatedCount > 0\">\n <span class=\"eval-stat-label\">Pass Rate</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.autoPassRate.toFixed(0) }}%</span>\n </div>\n </div>\n </div>\n\n <!-- Execution Card -->\n <div class=\"eval-summary-card\" *ngIf=\"evalPreferences.showExecution\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>Execution</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Completed</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.execCompletedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Success Rate</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.execSuccessRate.toFixed(0) }}%</span>\n </div>\n <div class=\"eval-stat-row\" *ngIf=\"evaluationMetrics.execErrorCount > 0 || evaluationMetrics.execTimeoutCount > 0\">\n <span class=\"eval-stat-label\">Issues</span>\n <span class=\"eval-stat-value error\" *ngIf=\"evaluationMetrics.execErrorCount > 0\">{{ evaluationMetrics.execErrorCount }} errors</span>\n <span class=\"eval-stat-value timeout\" *ngIf=\"evaluationMetrics.execTimeoutCount > 0\">{{ evaluationMetrics.execTimeoutCount }} timeouts</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Needs Review Section -->\n <div class=\"needs-review-section\" *ngIf=\"evalPreferences.showHuman && needsReviewItems.length > 0 && feedbacksLoaded\">\n <div class=\"needs-review-header\">\n <h3><i class=\"fa-solid fa-user-clock\"></i> Needs Review</h3>\n <span class=\"review-count\">{{ needsReviewItems.length }} items</span>\n </div>\n <div class=\"needs-review-list\">\n <div class=\"review-item\" *ngFor=\"let item of needsReviewItems.slice(0, 5)\"\n [class.high-priority]=\"item.priority === 'high'\"\n [class.medium-priority]=\"item.priority === 'medium'\"\n (click)=\"toggleRunExpanded(item.run.id)\">\n <div class=\"review-item-icon\">\n <i class=\"fa-solid fa-exclamation-triangle\" *ngIf=\"item.priority === 'high'\"></i>\n <i class=\"fa-solid fa-circle-dot\" *ngIf=\"item.priority === 'medium'\"></i>\n <i class=\"fa-solid fa-clock\" *ngIf=\"item.priority === 'low'\"></i>\n </div>\n <div class=\"review-item-content\">\n <span class=\"review-item-name\">{{ item.run.testName }}</span>\n <span class=\"review-item-reason\">{{ item.reason }}</span>\n </div>\n <div class=\"review-item-action\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div>\n </div>\n <div class=\"review-more\" *ngIf=\"needsReviewItems.length > 5\">\n <button kendoButton fillMode=\"flat\" (click)=\"changeTab('runs')\">\n View all {{ needsReviewItems.length }} items\n </button>\n </div>\n </div>\n </div>\n\n <!-- Progress Ring (when running) -->\n <div class=\"progress-section\" *ngIf=\"record.Status === 'Running' || record.Status === 'Pending'\">\n <div class=\"progress-info\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>Suite execution in progress...</span>\n </div>\n <div class=\"auto-refresh-notice\">\n <i class=\"fas fa-sync\"></i>\n Auto-refreshing every 5 seconds\n </div>\n </div>\n </div>\n\n <!-- Test Runs Tab -->\n <div class=\"runs-tab\" *ngIf=\"activeTab === 'runs'\">\n <!-- Toolbar -->\n <div class=\"runs-toolbar\" *ngIf=\"testRunsLoaded && testRuns.length > 0\">\n <div class=\"run-filters\">\n <button class=\"filter-btn\"\n [class.active]=\"runStatusFilter === null\"\n (click)=\"setRunStatusFilter(null)\">\n All ({{ testRuns.length }})\n </button>\n <button class=\"filter-btn passed\"\n [class.active]=\"runStatusFilter === 'Passed'\"\n (click)=\"setRunStatusFilter('Passed')\"\n *ngIf=\"getRunCountByStatus('Passed') > 0\">\n <i class=\"fas fa-check\"></i> Passed ({{ getRunCountByStatus('Passed') }})\n </button>\n <button class=\"filter-btn failed\"\n [class.active]=\"runStatusFilter === 'Failed'\"\n (click)=\"setRunStatusFilter('Failed')\"\n *ngIf=\"getRunCountByStatus('Failed') > 0\">\n <i class=\"fas fa-times\"></i> Failed ({{ getRunCountByStatus('Failed') }})\n </button>\n <button class=\"filter-btn error\"\n [class.active]=\"runStatusFilter === 'Error'\"\n (click)=\"setRunStatusFilter('Error')\"\n *ngIf=\"getRunCountByStatus('Error') > 0\">\n <i class=\"fas fa-exclamation\"></i> Error ({{ getRunCountByStatus('Error') }})\n </button>\n </div>\n <div class=\"runs-actions\">\n <button kendoButton (click)=\"exportToCSV()\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingTestRuns\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3,4,5]\">\n <div class=\"skeleton-sequence\"></div>\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 <!-- Test Runs List -->\n <div class=\"test-runs-list\" *ngIf=\"!loadingTestRuns && testRuns.length > 0\">\n <div class=\"test-run-card\" *ngFor=\"let run of getFilteredTestRuns()\">\n <div class=\"test-run-item\" (click)=\"toggleRunExpanded(run.ID)\">\n <div class=\"run-sequence\">{{ run.Sequence || '-' }}</div>\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\" [ngClass]=\"getRunStatusIcon(run.Status)\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header-row\">\n <div class=\"run-name\">{{ run.Test }}</div>\n <!-- Evaluation Badge -->\n <app-evaluation-badge\n [executionStatus]=\"run.Status\"\n [originalStatus]=\"run.Status\"\n [autoScore]=\"run.Score\"\n [humanRating]=\"getFeedbackRating(run.ID) || null\"\n [humanIsCorrect]=\"getHumanIsCorrect(run.ID)\"\n [hasHumanFeedback]=\"hasFeedback(run.ID)\"\n [preferences]=\"evalPreferences\"\n [mode]=\"'compact'\">\n </app-evaluation-badge>\n </div>\n <div class=\"run-meta\">\n <span class=\"run-duration\" *ngIf=\"run.DurationSeconds\">\n <i class=\"fas fa-clock\"></i> {{ run.DurationSeconds.toFixed(1) }}s\n </span>\n <span class=\"run-cost\" *ngIf=\"run.CostUSD\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.CostUSD.toFixed(6) }}\n </span>\n <mj-entity-link-pill\n *ngIf=\"run.TargetLogEntityID && run.TargetLogID\"\n [entityName]=\"run.TargetLogEntity\"\n [recordId]=\"run.TargetLogID\">\n </mj-entity-link-pill>\n </div>\n <div class=\"run-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-chip\" *ngFor=\"let tag of getRunTags(run)\">{{ tag }}</span>\n </div>\n </div>\n <div class=\"run-expand\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedRunId !== run.ID\" [class.fa-chevron-up]=\"expandedRunId === run.ID\"></i>\n </div>\n </div>\n\n <!-- Expanded Inline Feedback -->\n <div class=\"inline-feedback\" *ngIf=\"expandedRunId === run.ID\">\n <div class=\"feedback-divider\"></div>\n\n <div class=\"feedback-section\">\n <div class=\"feedback-label\">Quick Feedback</div>\n\n <div class=\"inline-rating\">\n <div class=\"rating-numbers\">\n <button *ngFor=\"let num of [1,2,3,4,5,6,7,8,9,10]\"\n type=\"button\"\n class=\"rating-btn\"\n [class.selected]=\"num === inlineRating\"\n [class.hover]=\"num === inlineHoverRating\"\n [class.low]=\"num <= 3\"\n [class.mid]=\"num >= 4 && num <= 6\"\n [class.high]=\"num >= 7\"\n (click)=\"setInlineRating(num); $event.stopPropagation()\"\n (mouseenter)=\"inlineHoverRating = num\"\n (mouseleave)=\"inlineHoverRating = 0\">\n {{ num }}\n </button>\n </div>\n <div class=\"rating-info\" *ngIf=\"inlineRating > 0\">\n <span class=\"rating-value\">{{ inlineRating }}/10</span>\n <span class=\"rating-label-text\">{{ getInlineRatingLabel() }}</span>\n </div>\n </div>\n\n <div class=\"correctness-row\">\n <span class=\"correctness-label\">Was it correct?</span>\n <div class=\"correctness-options\">\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"true\" [(ngModel)]=\"inlineIsCorrect\">\n <span>Yes</span>\n </label>\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"false\" [(ngModel)]=\"inlineIsCorrect\">\n <span>No</span>\n </label>\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"null\" [(ngModel)]=\"inlineIsCorrect\">\n <span>Not Sure</span>\n </label>\n </div>\n </div>\n\n <div class=\"comments-row\" (click)=\"$event.stopPropagation()\">\n <textarea\n class=\"feedback-textarea\"\n [(ngModel)]=\"inlineComments\"\n placeholder=\"Add comments or corrections...\"\n rows=\"3\"></textarea>\n </div>\n\n <div class=\"feedback-actions\" (click)=\"$event.stopPropagation()\">\n <button kendoButton (click)=\"openTestRun(run.ID)\">\n <i class=\"fas fa-external-link-alt\"></i> View Full Details\n </button>\n <button kendoButton\n themeColor=\"primary\"\n (click)=\"saveInlineFeedback()\"\n [disabled]=\"!canSubmitInlineFeedback() || savingInlineFeedback\">\n <i class=\"fas\" [ngClass]=\"savingInlineFeedback ? 'fa-spinner fa-spin' : 'fa-save'\"></i>\n {{ savingInlineFeedback ? 'Saving...' : (hasFeedback(run.ID) ? 'Update' : 'Save') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"testRunsLoaded && !loadingTestRuns && testRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-inbox\"></i>\n </div>\n <h4>No Test Runs Found</h4>\n <p>No test runs have been recorded for this suite execution.</p>\n </div>\n\n <!-- Filtered Empty -->\n <div class=\"empty-state\" *ngIf=\"testRunsLoaded && !loadingTestRuns && testRuns.length > 0 && getFilteredTestRuns().length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-filter\"></i>\n </div>\n <h4>No Matching Runs</h4>\n <p>No test runs match the current filter.</p>\n <button kendoButton (click)=\"setRunStatusFilter(null)\">Clear Filter</button>\n </div>\n </div>\n\n <!-- Details Tab -->\n <div class=\"details-tab\" *ngIf=\"activeTab === 'details'\">\n <div class=\"details-card\">\n <h3><i class=\"fas fa-info-circle\"></i> Run Information</h3>\n <div class=\"details-grid\">\n <div class=\"detail-item\">\n <div class=\"detail-label\">Run ID</div>\n <div class=\"detail-value monospace\">{{ record.ID }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Test Suite</div>\n <div class=\"detail-value\">\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\" *ngIf=\"testSuite\">{{ testSuite.Name }}</a>\n <span *ngIf=\"!testSuite\">Loading...</span>\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Status</div>\n <div class=\"detail-value\">\n <span class=\"status-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Run By</div>\n <div class=\"detail-value\">{{ record.RunByUser || '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\">Environment</div>\n <div class=\"detail-value\">{{ record.Environment || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Trigger Type</div>\n <div class=\"detail-value\">{{ record.TriggerType || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Git Commit</div>\n <div class=\"detail-value monospace\">{{ record.GitCommit || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Agent Version</div>\n <div class=\"detail-value\">{{ record.AgentVersion || 'N/A' }}</div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Analytics Tab -->\n <div class=\"analytics-tab\" *ngIf=\"activeTab === 'analytics'\">\n <!-- Loading State -->\n <div class=\"analytics-loading\" *ngIf=\"loadingTestRuns\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading test results...</span>\n </div>\n\n <!-- Summary Statistics - Moved to top for better overview -->\n <div class=\"analytics-section\" *ngIf=\"!loadingTestRuns && testRuns.length > 0\">\n <h3><i class=\"fas fa-chart-pie\"></i> Summary Statistics</h3>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-icon passed\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getPassedCount() }}</div>\n <div class=\"stat-label\">Passed</div>\n <div class=\"stat-percent\">{{ getPassedPercent().toFixed(1) }}%</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon failed\"><i class=\"fas fa-times-circle\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getFailedCount() }}</div>\n <div class=\"stat-label\">Failed</div>\n <div class=\"stat-percent\">{{ getFailedPercent().toFixed(1) }}%</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon score\"><i class=\"fas fa-star\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ (getAverageScore() * 100).toFixed(1) }}%</div>\n <div class=\"stat-label\">Avg Score</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon duration\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getAverageDuration().toFixed(1) }}s</div>\n <div class=\"stat-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon cost\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">${{ getTotalCost().toFixed(4) }}</div>\n <div class=\"stat-label\">Total Cost</div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Test Results Table -->\n <div class=\"analytics-section\" *ngIf=\"!loadingTestRuns && testRuns.length > 0\">\n <div class=\"analytics-header\">\n <h3><i class=\"fas fa-table\"></i> Test Results</h3>\n <div class=\"analytics-legend\">\n <span class=\"legend-item passed\"><i class=\"fas fa-check-circle\"></i> Passed</span>\n <span class=\"legend-item failed\"><i class=\"fas fa-times-circle\"></i> Failed</span>\n <span class=\"legend-item error\"><i class=\"fas fa-exclamation-circle\"></i> Error</span>\n <span class=\"legend-item skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n\n <!-- Results Table -->\n <div class=\"results-table-wrapper\">\n <table class=\"results-table\">\n <thead>\n <tr>\n <th class=\"seq-col\">#</th>\n <th class=\"name-col\">Test Name</th>\n <th class=\"status-col\" *ngIf=\"evalPreferences.showExecution\">Status</th>\n <th class=\"score-col\" *ngIf=\"evalPreferences.showAuto\">Auto Score</th>\n <th class=\"feedback-col\" *ngIf=\"evalPreferences.showHuman\">Human Score</th>\n <th class=\"duration-col\">Duration</th>\n <th class=\"cost-col\">Cost</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let run of testRuns; let i = index\"\n class=\"result-row\"\n [class.row-passed]=\"run.Status === 'Passed'\"\n [class.row-failed]=\"run.Status === 'Failed'\"\n [class.row-error]=\"run.Status === 'Error'\"\n [class.row-skipped]=\"run.Status === 'Skipped'\"\n (click)=\"openTestRun(run.ID)\">\n <td class=\"seq-col\">{{ i + 1 }}</td>\n <td class=\"name-col\">\n <div class=\"test-name-wrapper\">\n <span class=\"test-name\">{{ run.Test || 'Unknown Test' }}</span>\n <div class=\"test-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of getRunTags(run).slice(0, 2)\">{{ tag }}</span>\n </div>\n </div>\n </td>\n <td class=\"status-col\" *ngIf=\"evalPreferences.showExecution\">\n <span class=\"status-badge\" [ngClass]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-check-circle]=\"run.Status === 'Passed'\"\n [class.fa-times-circle]=\"run.Status === 'Failed'\"\n [class.fa-exclamation-circle]=\"run.Status === 'Error'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-spin]=\"run.Status === 'Running'\"></i>\n {{ run.Status }}\n </span>\n </td>\n <td class=\"score-col\" *ngIf=\"evalPreferences.showAuto\">\n <div class=\"score-display\" *ngIf=\"run.Score != null\">\n <div class=\"score-bar-mini\">\n <div class=\"score-fill\"\n [style.width.%]=\"run.Score * 100\"\n [class.high]=\"run.Score >= 0.8\"\n [class.medium]=\"run.Score >= 0.5 && run.Score < 0.8\"\n [class.low]=\"run.Score < 0.5\"></div>\n </div>\n <span class=\"score-text\">{{ (run.Score * 100).toFixed(0) }}%</span>\n </div>\n <span class=\"na-value\" *ngIf=\"run.Score == null\">\u2014</span>\n </td>\n <td class=\"feedback-col\" *ngIf=\"evalPreferences.showHuman\">\n <div class=\"feedback-display\" *ngIf=\"hasFeedback(run.ID)\">\n <span class=\"feedback-rating\" [class.low]=\"getFeedbackRating(run.ID) <= 3\" [class.mid]=\"getFeedbackRating(run.ID) >= 4 && getFeedbackRating(run.ID) <= 6\" [class.high]=\"getFeedbackRating(run.ID) >= 7\">\n {{ getFeedbackRating(run.ID) }}/10\n </span>\n <span class=\"feedback-correctness\" *ngIf=\"getHumanIsCorrect(run.ID) !== null\">\n <i class=\"fas\" [class.fa-check]=\"getHumanIsCorrect(run.ID) === true\" [class.fa-times]=\"getHumanIsCorrect(run.ID) === false\" [class.correct]=\"getHumanIsCorrect(run.ID) === true\" [class.incorrect]=\"getHumanIsCorrect(run.ID) === false\"></i>\n </span>\n </div>\n <span class=\"na-value needs-review\" *ngIf=\"!hasFeedback(run.ID)\">\n <i class=\"fas fa-user-clock\"></i>\n </span>\n </td>\n <td class=\"duration-col\">\n <span *ngIf=\"run.DurationSeconds\">{{ run.DurationSeconds.toFixed(1) }}s</span>\n <span class=\"na-value\" *ngIf=\"!run.DurationSeconds\">\u2014</span>\n </td>\n <td class=\"cost-col\">\n <span *ngIf=\"run.CostUSD\">${{ run.CostUSD.toFixed(4) }}</span>\n <span class=\"na-value\" *ngIf=\"!run.CostUSD\">\u2014</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"!loadingTestRuns && testRunsLoaded && testRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-bar\"></i>\n </div>\n <h4>No Test Results Yet</h4>\n <p>Test runs will appear here once the suite execution completes.</p>\n </div>\n </div>\n\n <!-- Execution Tab -->\n <div class=\"execution-tab\" *ngIf=\"activeTab === 'execution'\">\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 </div>\n\n <!-- Keyboard Shortcuts Toggle Button -->\n <button class=\"shortcuts-toggle\" (click)=\"toggleShortcuts()\" [title]=\"showShortcuts ? 'Hide keyboard shortcuts' : 'Show keyboard shortcuts'\">\n <i class=\"fas fa-keyboard\"></i>\n </button>\n\n <!-- Keyboard Shortcuts Hint (Desktop Only) -->\n <div class=\"keyboard-shortcuts\" *ngIf=\"showShortcuts\">\n <div class=\"shortcuts-header\">\n <i class=\"fas fa-keyboard\"></i>\n Shortcuts\n <button class=\"shortcuts-close\" (click)=\"toggleShortcuts()\" title=\"Hide shortcuts\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcut-list\">\n <div class=\"shortcut-item\">\n <span>Refresh</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Re-run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Shift</kbd><kbd>R</kbd></span>\n </div>\n <div class=\"shortcut-item\">\n <span>Switch Tabs</span>\n <span class=\"shortcut-keys\"><kbd>1</kbd>-<kbd>5</kbd></span>\n </div>\n </div>\n </div>\n</div>\n", styles: ["/* ===================================\n Test Suite Run Form - Premium UX\n World-class responsive design\n =================================== */\n\n/* CSS Custom Properties */\n:host {\n --suite-run-primary: #3b82f6;\n --suite-run-primary-light: #eff6ff;\n --suite-run-success: #10b981;\n --suite-run-success-light: #ecfdf5;\n --suite-run-danger: #ef4444;\n --suite-run-danger-light: #fef2f2;\n --suite-run-warning: #f59e0b;\n --suite-run-warning-light: #fffbeb;\n --suite-run-info: #8b5cf6;\n --suite-run-info-light: #f5f3ff;\n --suite-run-neutral: #6b7280;\n --suite-run-neutral-light: #f9fafb;\n --suite-run-bg: #f8fafc;\n --suite-run-card: #ffffff;\n --suite-run-border: #e2e8f0;\n --suite-run-text: #1e293b;\n --suite-run-text-secondary: #64748b;\n --suite-run-radius: 12px;\n --suite-run-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);\n --suite-run-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --suite-run-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* Base Container */\n.test-suite-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--suite-run-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n/* ===================================\n Header Section\n =================================== */\n.suite-run-header {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n padding: 20px 24px;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n margin-bottom: 16px;\n}\n\n.breadcrumb a {\n color: var(--suite-run-primary);\n text-decoration: none;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: var(--suite-run-transition);\n}\n\n.breadcrumb a:hover {\n color: #2563eb;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: #cbd5e1;\n}\n\n.breadcrumb .current {\n color: var(--suite-run-text);\n font-weight: 500;\n}\n\n/* Header Content */\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n}\n\n.suite-run-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--suite-run-radius);\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(--suite-run-shadow);\n}\n\n.suite-run-info h1 {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.suite-run-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-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 text-transform: uppercase;\n letter-spacing: 0.025em;\n}\n\n.status-badge.status-completed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-badge.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-badge.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-badge.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-badge.status-cancelled {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.meta-tag {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--suite-run-neutral-light);\n border-radius: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.meta-tag i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* ===================================\n Metrics Bar\n =================================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 20px;\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(--suite-run-border);\n border-radius: 10px;\n padding: 14px;\n transition: var(--suite-run-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\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(--suite-run-card);\n border-radius: 10px;\n color: var(--suite-run-primary);\n font-size: 16px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-content {\n flex: 1;\n min-width: 0;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.metric-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n margin-top: 2px;\n}\n\n/* ===================================\n Results Summary\n =================================== */\n.results-summary {\n display: flex;\n gap: 12px;\n padding-top: 20px;\n border-top: 1px solid var(--suite-run-border);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.result-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n flex-shrink: 0;\n transition: var(--suite-run-transition);\n}\n\n.result-item:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.result-icon {\n font-size: 24px;\n}\n\n.result-content {\n display: flex;\n flex-direction: column;\n}\n\n.result-count {\n font-size: 20px;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.result-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-item.passed .result-icon,\n.result-item.passed .result-count {\n color: var(--suite-run-success);\n}\n\n.result-item.failed .result-icon,\n.result-item.failed .result-count {\n color: var(--suite-run-danger);\n}\n\n.result-item.error .result-icon,\n.result-item.error .result-count {\n color: var(--suite-run-warning);\n}\n\n.result-item.skipped .result-icon,\n.result-item.skipped .result-count {\n color: var(--suite-run-neutral);\n}\n\n.result-item.total .result-icon,\n.result-item.total .result-count {\n color: var(--suite-run-primary);\n}\n\n/* ===================================\n Tabs\n =================================== */\n.tabs-container {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 24px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: 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: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--suite-run-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab:hover {\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tab.active {\n color: var(--suite-run-primary);\n border-bottom-color: var(--suite-run-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--suite-run-border);\n color: var(--suite-run-text-secondary);\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: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.tab-shortcut {\n display: none;\n width: 18px;\n height: 18px;\n background: var(--suite-run-neutral-light);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n}\n\n/* ===================================\n Tab Content\n =================================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n/* ===================================\n Overview Tab\n =================================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n max-width: 800px;\n margin: 0 auto;\n width: 100%;\n}\n\n.result-hero {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 48px 32px;\n text-align: center;\n border: 2px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n}\n\n.result-hero.passed {\n background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);\n border-color: var(--suite-run-success);\n}\n\n.result-hero.failed {\n background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);\n border-color: var(--suite-run-danger);\n}\n\n.result-hero.running {\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-color: var(--suite-run-primary);\n}\n\n.result-hero.pending {\n background: linear-gradient(135deg, #f5f3ff 0%, #ede9fe 100%);\n border-color: var(--suite-run-info);\n}\n\n.result-hero-icon {\n font-size: 72px;\n margin-bottom: 20px;\n}\n\n.result-hero.passed .result-hero-icon {\n color: var(--suite-run-success);\n}\n\n.result-hero.failed .result-hero-icon {\n color: var(--suite-run-danger);\n}\n\n.result-hero.running .result-hero-icon {\n color: var(--suite-run-primary);\n}\n\n.result-hero.pending .result-hero-icon {\n color: var(--suite-run-info);\n}\n\n.result-hero-text h2 {\n margin: 0 0 16px 0;\n font-size: 32px;\n font-weight: 800;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.result-hero-stats {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 32px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.stat-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-divider {\n width: 1px;\n height: 40px;\n background: var(--suite-run-border);\n}\n\n/* Progress Section */\n.progress-section {\n background: var(--suite-run-primary-light);\n border: 1px solid rgba(59, 130, 246, 0.2);\n border-radius: var(--suite-run-radius);\n padding: 20px;\n text-align: center;\n}\n\n.progress-info {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 500;\n color: var(--suite-run-primary);\n margin-bottom: 8px;\n}\n\n.progress-info i {\n font-size: 20px;\n}\n\n.auto-refresh-notice {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n/* ===================================\n Test Runs Tab\n =================================== */\n.runs-tab {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n/* Loading Skeleton */\n.loading-state {\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\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: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 1px solid var(--suite-run-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 50%;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 8px;\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 background: linear-gradient(90deg, #f1f5f9 25%, #e2e8f0 50%, #f1f5f9 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 4px;\n}\n\n.skeleton-line.wide {\n width: 70%;\n}\n\n.skeleton-line.narrow {\n width: 40%;\n}\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Test Runs List */\n.test-runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover {\n background: var(--suite-run-primary-light);\n border-color: #93c5fd;\n transform: translateX(4px);\n}\n\n.test-run-item:active {\n transform: translateX(2px);\n}\n\n.run-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n color: white;\n font-size: 16px;\n flex-shrink: 0;\n box-shadow: var(--suite-run-shadow);\n}\n\n.run-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-status {\n font-weight: 700;\n}\n\n.run-score,\n.run-duration {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-score i,\n.run-duration i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.test-run-item > i {\n color: #cbd5e1;\n font-size: 14px;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover > i {\n color: var(--suite-run-primary);\n transform: translateX(4px);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 2px dashed var(--suite-run-border);\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(--suite-run-neutral-light);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: #cbd5e1;\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n color: var(--suite-run-text-secondary);\n max-width: 300px;\n}\n\n/* ===================================\n Details Tab\n =================================== */\n.details-tab {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n.details-card {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.details-card h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.details-card h3 i {\n color: var(--suite-run-primary);\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 20px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--suite-run-text);\n word-wrap: break-word;\n}\n\n.detail-value.monospace {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n background: var(--suite-run-neutral-light);\n padding: 6px 10px;\n border-radius: 6px;\n}\n\n.detail-value a {\n color: var(--suite-run-primary);\n text-decoration: none;\n font-weight: 500;\n transition: var(--suite-run-transition);\n}\n\n.detail-value a:hover {\n color: #2563eb;\n text-decoration: underline;\n}\n\n.status-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-inline.status-completed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-inline.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-inline.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-inline.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-inline.status-cancelled {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n/* ===================================\n Keyboard Shortcuts\n =================================== */\n/* Toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n box-shadow: var(--suite-run-shadow);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--suite-run-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n padding: 12px 16px;\n box-shadow: var(--suite-run-shadow-lg);\n font-size: 12px;\n z-index: 100;\n opacity: 0.9;\n transition: var(--suite-run-transition);\n}\n\n.keyboard-shortcuts:hover {\n opacity: 1;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.shortcuts-header i {\n color: var(--suite-run-primary);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--suite-run-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--suite-run-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--suite-run-text);\n background: var(--suite-run-border);\n}\n\n.shortcut-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.shortcut-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 16px;\n}\n\n.shortcut-item span:first-child {\n color: var(--suite-run-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\nkbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: linear-gradient(180deg, #f8fafc 0%, #e2e8f0 100%);\n border: 1px solid #cbd5e1;\n border-radius: 4px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text);\n box-shadow: 0 1px 0 #94a3b8;\n}\n\n/* ===================================\n Responsive Design - Tablet\n =================================== */\n@media (max-width: 1024px) {\n .suite-run-header {\n padding: 16px 20px;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .result-hero-stats {\n flex-direction: column;\n gap: 16px;\n }\n\n .stat-divider {\n display: none;\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .tab-shortcut {\n display: none;\n }\n}\n\n/* ===================================\n Responsive Design - Mobile\n =================================== */\n@media (max-width: 768px) {\n .suite-run-header {\n padding: 16px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .suite-run-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .suite-run-info h1 {\n font-size: 20px;\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: 8px;\n }\n\n .metric-card {\n padding: 12px;\n flex-direction: column;\n text-align: center;\n gap: 8px;\n }\n\n .metric-icon {\n width: 36px;\n height: 36px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .results-summary {\n gap: 8px;\n padding-top: 16px;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 8px;\n margin-bottom: -8px;\n }\n\n .result-item {\n padding: 10px 12px;\n min-width: 90px;\n }\n\n .result-icon {\n font-size: 20px;\n }\n\n .result-count {\n font-size: 18px;\n }\n\n .tabs {\n padding: 0 16px;\n }\n\n .tab {\n padding: 14px 16px;\n font-size: 13px;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .result-hero {\n padding: 32px 20px;\n }\n\n .result-hero-icon {\n font-size: 56px;\n }\n\n .result-hero-text h2 {\n font-size: 24px;\n }\n\n .stat-value {\n font-size: 20px;\n }\n\n .test-run-item {\n padding: 14px;\n }\n\n .run-sequence {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n\n .run-icon {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .run-name {\n font-size: 13px;\n }\n\n .run-meta {\n gap: 10px;\n font-size: 11px;\n }\n\n .empty-state {\n padding: 40px 16px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\n }\n\n .details-card {\n padding: 16px;\n }\n\n .details-grid {\n gap: 16px;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===================================\n Responsive Design - Small Mobile\n =================================== */\n@media (max-width: 480px) {\n .suite-run-header {\n padding: 12px;\n }\n\n .breadcrumb {\n font-size: 12px;\n margin-bottom: 12px;\n }\n\n .suite-run-icon {\n width: 44px;\n height: 44px;\n font-size: 18px;\n }\n\n .suite-run-info h1 {\n font-size: 18px;\n }\n\n .suite-run-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .meta-tag {\n font-size: 11px;\n padding: 3px 8px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card {\n padding: 10px;\n gap: 6px;\n }\n\n .metric-icon {\n width: 32px;\n height: 32px;\n font-size: 14px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .metric-label {\n font-size: 9px;\n }\n\n .result-item {\n padding: 8px 10px;\n min-width: 80px;\n gap: 8px;\n }\n\n .result-icon {\n font-size: 18px;\n }\n\n .result-count {\n font-size: 16px;\n }\n\n .result-label {\n font-size: 9px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .result-hero {\n padding: 24px 16px;\n }\n\n .result-hero-icon {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .result-hero-text h2 {\n font-size: 20px;\n margin-bottom: 12px;\n }\n\n .stat-value {\n font-size: 18px;\n }\n\n .stat-label {\n font-size: 10px;\n }\n\n .progress-section {\n padding: 16px;\n }\n\n .progress-info {\n font-size: 14px;\n }\n\n .test-run-item {\n padding: 12px;\n gap: 10px;\n }\n\n .run-sequence {\n width: 24px;\n height: 24px;\n font-size: 11px;\n }\n\n .run-icon {\n width: 32px;\n height: 32px;\n font-size: 12px;\n border-radius: 8px;\n }\n\n .run-name {\n font-size: 12px;\n margin-bottom: 3px;\n }\n\n .run-meta {\n gap: 8px;\n font-size: 10px;\n }\n\n .empty-state {\n padding: 32px 12px;\n }\n\n .empty-state h4 {\n font-size: 16px;\n }\n\n .empty-state p {\n font-size: 13px;\n }\n\n .details-card {\n padding: 14px;\n }\n\n .details-card h3 {\n font-size: 14px;\n margin-bottom: 16px;\n }\n\n .detail-label {\n font-size: 10px;\n }\n\n .detail-value {\n font-size: 13px;\n }\n}\n\n/* ===================================\n Touch Device Optimizations\n =================================== */\n@media (hover: none) and (pointer: coarse) {\n .test-run-item {\n min-height: 64px;\n }\n\n .test-run-item:hover {\n transform: none;\n background: var(--suite-run-card);\n border-color: var(--suite-run-border);\n }\n\n .test-run-item:active {\n background: var(--suite-run-primary-light);\n border-color: #93c5fd;\n }\n\n .tab:hover {\n background: transparent;\n color: var(--suite-run-text-secondary);\n }\n\n .tab:active {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n }\n\n .metric-card:hover {\n transform: none;\n box-shadow: none;\n }\n\n .result-item:hover {\n transform: none;\n box-shadow: none;\n }\n\n .keyboard-shortcuts {\n display: none;\n }\n}\n\n/* ===================================\n Print Styles\n =================================== */\n@media print {\n .suite-run-header {\n background: white;\n box-shadow: none;\n border-bottom: 2px solid #000;\n }\n\n .tabs-container,\n .header-actions,\n .keyboard-shortcuts {\n display: none;\n }\n\n .tab-content {\n padding: 20px 0;\n }\n\n .result-hero,\n .test-run-item,\n .details-card {\n box-shadow: none;\n border: 1px solid #ccc;\n }\n}\n\n/* ===================================\n Dark Mode Support (Future)\n =================================== */\n@media (prefers-color-scheme: dark) {\n /* Ready for dark mode implementation */\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(59, 130, 246, 0.04) 0%, rgba(59, 130, 246, 0.08) 100%);\n border: 1px solid rgba(59, 130, 246, 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(--suite-run-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: var(--suite-run-primary-light);\n color: var(--suite-run-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(--suite-run-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(--suite-run-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.tags-bar-edit:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\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(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n border-radius: 10px;\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(59, 130, 246, 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: var(--suite-run-primary-light);\n border-bottom: 1px solid rgba(59, 130, 246, 0.2);\n}\n\n.tags-editor-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-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(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n color: var(--suite-run-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(--suite-run-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--suite-run-transition);\n}\n\n.tag-remove-btn:hover {\n opacity: 1;\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.tags-empty-hint {\n font-size: 12px;\n color: var(--suite-run-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(--suite-run-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--suite-run-neutral-light);\n}\n\n.tag-text-input:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n background: var(--suite-run-card);\n box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n.tag-text-input::placeholder {\n color: var(--suite-run-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(--suite-run-neutral-light);\n border-top: 1px solid var(--suite-run-border);\n}\n\n/* ===================================\n Runs Toolbar\n =================================== */\n.runs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.run-filters {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-btn {\n padding: 6px 14px;\n border: 1px solid var(--suite-run-border);\n background: var(--suite-run-card);\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n}\n\n.filter-btn.active {\n background: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n color: white;\n}\n\n.filter-btn.passed:hover,\n.filter-btn.passed.active {\n background: var(--suite-run-success);\n border-color: var(--suite-run-success);\n color: white;\n}\n\n.filter-btn.failed:hover,\n.filter-btn.failed.active {\n background: var(--suite-run-danger);\n border-color: var(--suite-run-danger);\n color: white;\n}\n\n.filter-btn.error:hover,\n.filter-btn.error.active {\n background: var(--suite-run-warning);\n border-color: var(--suite-run-warning);\n color: white;\n}\n\n.runs-actions {\n display: flex;\n gap: 8px;\n}\n\n/* ===================================\n Test Run Card (Expandable)\n =================================== */\n.test-run-card {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n margin-bottom: 10px;\n}\n\n.test-run-card:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover {\n background: var(--suite-run-primary-light);\n}\n\n.run-header-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-feedback-indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.run-feedback-indicator i {\n font-size: 10px;\n}\n\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 6px;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 500;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border: 1px solid #bfdbfe;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: #1d4ed8;\n}\n\n.run-expand {\n color: var(--suite-run-text-secondary);\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover .run-expand {\n color: var(--suite-run-primary);\n}\n\n.run-cost {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-cost i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n/* ===================================\n Inline Feedback\n =================================== */\n.inline-feedback {\n padding: 0 16px 16px;\n animation: slideDown 0.2s ease-out;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.feedback-divider {\n height: 1px;\n background: var(--suite-run-border);\n margin-bottom: 16px;\n}\n\n.feedback-section {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.inline-rating {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.rating-numbers {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.rating-btn {\n width: 36px;\n height: 36px;\n border: 2px solid var(--suite-run-border);\n border-radius: 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.rating-btn:hover,\n.rating-btn.hover {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.rating-btn.low:hover,\n.rating-btn.low.hover {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.rating-btn.mid:hover,\n.rating-btn.mid.hover {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.rating-btn.high:hover,\n.rating-btn.high.hover {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.rating-btn.selected {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n}\n\n.rating-btn.selected.low {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger);\n color: white;\n}\n\n.rating-btn.selected.mid {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning);\n color: white;\n}\n\n.rating-btn.selected.high {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success);\n color: white;\n}\n\n.rating-info {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--suite-run-neutral-light);\n border-radius: 8px;\n}\n\n.rating-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.rating-label-text {\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.correctness-row {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.correctness-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.correctness-options {\n display: flex;\n gap: 16px;\n}\n\n.radio-opt {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.radio-opt input[type=\"radio\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.comments-row {\n width: 100%;\n}\n\n.feedback-textarea {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n}\n\n.feedback-textarea:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);\n}\n\n.feedback-actions {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding-top: 8px;\n}\n\n/* ===================================\n Mobile Responsive Updates\n =================================== */\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 .runs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .run-filters {\n justify-content: center;\n }\n\n .runs-actions {\n justify-content: center;\n }\n\n .rating-numbers {\n justify-content: center;\n }\n\n .rating-btn {\n width: 32px;\n height: 32px;\n font-size: 12px;\n }\n\n .correctness-row {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .feedback-actions {\n flex-direction: column;\n }\n\n .feedback-actions button {\n width: 100%;\n }\n}\n\n/* ===================================\n Animations\n =================================== */\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.result-hero.running .result-hero-icon {\n animation: pulse 2s ease-in-out infinite;\n}\n\n/* Tab content fade in */\n.overview-tab,\n.runs-tab,\n.details-tab,\n.analytics-tab {\n animation: fadeIn 0.3s ease;\n}\n\n/* ===================================\n Analytics Tab\n =================================== */\n.analytics-tab {\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.analytics-section {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.analytics-section h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-section h3 i {\n color: var(--suite-run-primary);\n}\n\n.analytics-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-header h3 {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.analytics-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.legend-item.passed {\n color: var(--suite-run-success);\n}\n\n.legend-item.failed {\n color: var(--suite-run-danger);\n}\n\n.legend-item.error {\n color: var(--suite-run-warning);\n}\n\n.legend-item.skipped {\n color: var(--suite-run-neutral);\n}\n\n/* Performance Matrix */\n.performance-matrix {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.matrix-row {\n display: grid;\n grid-template-columns: 2fr 120px 150px 100px 100px;\n border-bottom: 1px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n cursor: pointer;\n}\n\n.matrix-row:last-child {\n border-bottom: none;\n}\n\n.matrix-row:hover:not(.matrix-header-row) {\n background: var(--suite-run-primary-light);\n}\n\n.matrix-row.passed {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.matrix-row.failed {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.matrix-row.error {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.matrix-row.skipped {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n.matrix-header-row {\n background: var(--suite-run-neutral-light);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n cursor: default;\n}\n\n.matrix-cell {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n}\n\n.test-name-cell {\n gap: 12px;\n}\n\n.test-sequence {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.test-name {\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.status-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-indicator.status-passed {\n color: var(--suite-run-success);\n}\n\n.status-indicator.status-failed {\n color: var(--suite-run-danger);\n}\n\n.status-indicator.status-error {\n color: var(--suite-run-warning);\n}\n\n.status-indicator.status-skipped {\n color: var(--suite-run-neutral);\n}\n\n.status-indicator.status-pending {\n color: var(--suite-run-info);\n}\n\n.status-indicator.status-running {\n color: var(--suite-run-primary);\n}\n\n.score-bar {\n position: relative;\n width: 100%;\n height: 20px;\n background: var(--suite-run-neutral-light);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.score-fill {\n height: 100%;\n border-radius: 10px;\n transition: width 0.3s ease;\n}\n\n.score-fill.high {\n background: linear-gradient(90deg, var(--suite-run-success) 0%, #34d399 100%);\n}\n\n.score-fill.medium {\n background: linear-gradient(90deg, var(--suite-run-warning) 0%, #fbbf24 100%);\n}\n\n.score-fill.low {\n background: linear-gradient(90deg, var(--suite-run-danger) 0%, #f87171 100%);\n}\n\n.score-text {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.na-value {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n/* Summary Statistics Grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.stat-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--suite-run-border);\n border-radius: 12px;\n transition: var(--suite-run-transition);\n}\n\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.stat-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n font-size: 20px;\n}\n\n.stat-icon.passed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.stat-icon.failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.stat-icon.score {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.stat-icon.duration {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.stat-icon.cost {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.stat-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.stat-card .stat-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-card .stat-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-percent {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n/* Responsive Analytics */\n@media (max-width: 768px) {\n .analytics-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .matrix-row {\n grid-template-columns: 1fr;\n gap: 8px;\n padding: 12px;\n }\n\n .matrix-header-row {\n display: none;\n }\n\n .matrix-cell {\n padding: 4px 0;\n }\n\n .test-name-cell::before,\n .status-cell::before,\n .score-cell::before,\n .duration-cell::before,\n .cost-cell::before {\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n margin-right: 8px;\n min-width: 80px;\n }\n\n .status-cell::before { content: 'Status:'; }\n .score-cell::before { content: 'Score:'; }\n .duration-cell::before { content: 'Duration:'; }\n .cost-cell::before { content: 'Cost:'; }\n\n .stats-grid {\n grid-template-columns: 1fr 1fr;\n }\n\n .stat-card {\n padding: 16px;\n }\n\n .stat-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .stat-card .stat-value {\n font-size: 20px;\n }\n}\n\n/* Focus States for Accessibility */\n.tab:focus-visible,\n.test-run-item:focus-visible,\nbutton:focus-visible {\n outline: 2px solid var(--suite-run-primary);\n outline-offset: 2px;\n}\n\n/* ===================================\n Analytics Loading State\n =================================== */\n.analytics-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--suite-run-text-secondary);\n}\n\n.analytics-loading i {\n font-size: 32px;\n color: var(--suite-run-primary);\n}\n\n/* ===================================\n Results Table\n =================================== */\n.results-table-wrapper {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.results-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.results-table thead {\n background: var(--suite-run-neutral-light);\n}\n\n.results-table th {\n padding: 12px 16px;\n text-align: left;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.results-table td {\n padding: 12px 16px;\n border-bottom: 1px solid #f1f5f9;\n vertical-align: middle;\n}\n\n.results-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n/* Column widths - Fixed columns fit content, name column takes remainder (max 50%) */\n.seq-col {\n width: 40px;\n min-width: 40px;\n text-align: center;\n white-space: nowrap;\n}\n\n.name-col {\n /* Take remaining space, but cap at 50% of table width */\n width: auto;\n max-width: 50%;\n}\n\n.status-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n}\n\n.score-col {\n width: 1%; /* Shrink to fit content */\n min-width: 120px; /* Score bar needs some minimum width */\n white-space: nowrap;\n}\n\n.duration-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: right;\n}\n\n.cost-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: right;\n}\n\n/* Result Row */\n.result-row {\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.result-row:hover {\n background: var(--suite-run-primary-light);\n}\n\n.result-row.row-passed {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.result-row.row-failed {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.result-row.row-error {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.result-row.row-skipped {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n/* Test Name Wrapper */\n.test-name-wrapper {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.test-name-wrapper .test-name {\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.test-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n/* Score Display */\n.score-display {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.score-bar-mini {\n flex: 1;\n height: 6px;\n background: var(--suite-run-neutral-light);\n border-radius: 3px;\n overflow: hidden;\n min-width: 60px;\n}\n\n.score-bar-mini .score-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.score-bar-mini .score-fill.high {\n background: var(--suite-run-success);\n}\n\n.score-bar-mini .score-fill.medium {\n background: var(--suite-run-warning);\n}\n\n.score-bar-mini .score-fill.low {\n background: var(--suite-run-danger);\n}\n\n.score-display .score-text {\n position: static;\n transform: none;\n font-size: 12px;\n font-weight: 600;\n color: var(--suite-run-text);\n min-width: 35px;\n text-align: right;\n}\n\n/* Status Badge in Table */\n.results-table .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.results-table .status-badge.status-passed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.results-table .status-badge.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.results-table .status-badge.status-error {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.results-table .status-badge.status-skipped {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.results-table .status-badge.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.results-table .status-badge.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n/* Responsive Results Table */\n@media (max-width: 768px) {\n .results-table-wrapper {\n overflow-x: auto;\n }\n\n .results-table {\n min-width: 600px;\n }\n\n .results-table th,\n .results-table td {\n padding: 10px 12px;\n }\n\n .name-col {\n min-width: 150px;\n }\n}\n\n/* ===================================\n High Contrast Mode\n =================================== */\n@media (prefers-contrast: high) {\n .status-badge,\n .status-inline {\n border: 2px solid currentColor;\n }\n\n .test-run-item {\n border-width: 2px;\n }\n\n .tab.active {\n border-bottom-width: 4px;\n }\n}\n\n/* ===================================\n Evaluation Summary\n =================================== */\n.evaluation-summary {\n margin-top: 20px;\n}\n\n.eval-summary-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 16px;\n}\n\n.eval-summary-card {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n}\n\n.eval-summary-card:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.eval-card-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-bottom: 1px solid var(--suite-run-border);\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-card-header i {\n color: var(--suite-run-primary);\n}\n\n.eval-card-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.eval-stat-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.eval-stat-label {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.eval-stat-value {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-stat-value.correct {\n color: var(--suite-run-success);\n}\n\n.eval-stat-value.incorrect {\n color: var(--suite-run-danger);\n font-weight: 500;\n font-size: 12px;\n}\n\n.eval-stat-value.error {\n color: var(--suite-run-danger);\n}\n\n.eval-stat-value.timeout {\n color: var(--suite-run-warning);\n}\n\n.eval-card-footer {\n padding: 10px 16px;\n background: var(--suite-run-warning-light);\n border-top: 1px solid rgba(245, 158, 11, 0.2);\n}\n\n.pending-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-warning);\n}\n\n.pending-badge i {\n font-size: 11px;\n}\n\n/* ===================================\n Needs Review Section\n =================================== */\n.needs-review-section {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n}\n\n.needs-review-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 20px;\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border-bottom: 1px solid rgba(245, 158, 11, 0.3);\n}\n\n.needs-review-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: #92400e;\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.needs-review-header h3 i {\n font-size: 16px;\n}\n\n.review-count {\n font-size: 12px;\n font-weight: 500;\n color: #92400e;\n background: rgba(255, 255, 255, 0.6);\n padding: 2px 10px;\n border-radius: 12px;\n}\n\n.needs-review-list {\n padding: 8px;\n}\n\n.review-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 8px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.review-item:hover {\n background: var(--suite-run-primary-light);\n}\n\n.review-item-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.review-item.high-priority .review-item-icon {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.review-item.medium-priority .review-item-icon {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.review-item:not(.high-priority):not(.medium-priority) .review-item-icon {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.review-item-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.review-item-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.review-item-reason {\n font-size: 11px;\n color: var(--suite-run-text-secondary);\n}\n\n.review-item-action {\n color: var(--suite-run-text-secondary);\n font-size: 12px;\n}\n\n.review-item:hover .review-item-action {\n color: var(--suite-run-primary);\n}\n\n.review-more {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--suite-run-border);\n}\n\n/* Mobile Responsive for Evaluation */\n@media (max-width: 768px) {\n .eval-summary-grid {\n grid-template-columns: 1fr;\n }\n\n .eval-card-header {\n padding: 10px 14px;\n font-size: 12px;\n }\n\n .eval-card-body {\n padding: 12px 14px;\n }\n\n .needs-review-header {\n padding: 12px 16px;\n }\n\n .needs-review-header h3 {\n font-size: 13px;\n }\n\n .review-item {\n padding: 10px 12px;\n }\n\n .review-item-icon {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n}\n\n/* ===================================\n Feedback Column in Analytics Table\n =================================== */\n.feedback-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: center;\n}\n\n.feedback-display {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.feedback-rating {\n font-size: 13px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--suite-run-neutral-light);\n}\n\n.feedback-rating.low {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.feedback-rating.mid {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.feedback-rating.high {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.feedback-correctness i {\n font-size: 12px;\n}\n\n.feedback-correctness i.correct {\n color: var(--suite-run-success);\n}\n\n.feedback-correctness i.incorrect {\n color: var(--suite-run-danger);\n}\n\n.na-value.needs-review {\n color: var(--suite-run-warning);\n opacity: 0.7;\n}\n\n.na-value.needs-review i {\n font-size: 14px;\n}\n"] }]
2276
+ }], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i3.TestingDialogService }, { type: i3.EvaluationPreferencesService }, { type: i0.ViewContainerRef }], { handleKeyboardShortcut: [{
2277
+ type: HostListener,
2278
+ args: ['document:keydown', ['$event']]
2279
+ }] }); })();
2280
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestSuiteRunFormComponentExtended, { className: "TestSuiteRunFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-run-form.component.ts", lineNumber: 34 }); })();
567
2281
  export function LoadTestSuiteRunFormComponentExtended() {
568
2282
  // Prevents tree-shaking
569
2283
  }