@memberjunction/ng-core-entity-forms 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +16 -17
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +16 -30
- package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.js +9 -10
- package/dist/lib/custom/EntityActions/entityaction.form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +7 -7
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.js +195 -112
- package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.d.ts +4 -1
- package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +401 -380
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +4 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +539 -518
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +4 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +535 -518
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/custom-forms.module.d.ts +48 -52
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +11 -25
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.js +141 -113
- package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgentExample/aiagentexample.form.component.js +28 -14
- package/dist/lib/generated/Entities/AIAgentExample/aiagentexample.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgentNote/aiagentnote.form.component.js +26 -12
- package/dist/lib/generated/Entities/AIAgentNote/aiagentnote.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgentRun/aiagentrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIAgentRun/aiagentrun.form.component.js +67 -47
- package/dist/lib/generated/Entities/AIAgentRun/aiagentrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIAgentRunStep/aiagentrunstep.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIAgentRunStep/aiagentrunstep.form.component.js +18 -24
- package/dist/lib/generated/Entities/AIAgentRunStep/aiagentrunstep.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/AIResultCache/airesultcache.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/AIResultCache/airesultcache.form.component.js +11 -17
- package/dist/lib/generated/Entities/AIResultCache/airesultcache.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/APIApplication/apiapplication.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/APIApplication/apiapplication.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/APIApplication/apiapplication.form.component.js +120 -0
- package/dist/lib/generated/Entities/APIApplication/apiapplication.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/APIApplicationScope/apiapplicationscope.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/APIApplicationScope/apiapplicationscope.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/APIApplicationScope/apiapplicationscope.form.component.js +75 -0
- package/dist/lib/generated/Entities/APIApplicationScope/apiapplicationscope.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/APIKey/apikey.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/APIKey/apikey.form.component.js +25 -7
- package/dist/lib/generated/Entities/APIKey/apikey.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/APIKeyApplication/apikeyapplication.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/APIKeyApplication/apikeyapplication.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/APIKeyApplication/apikeyapplication.form.component.js +61 -0
- package/dist/lib/generated/Entities/APIKeyApplication/apikeyapplication.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/APIKeyScope/apikeyscope.form.component.js +17 -9
- package/dist/lib/generated/Entities/APIKeyScope/apikeyscope.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/APIKeyUsageLog/apikeyusagelog.form.component.js +19 -7
- package/dist/lib/generated/Entities/APIKeyUsageLog/apikeyusagelog.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/APIScope/apiscope.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/APIScope/apiscope.form.component.js +67 -11
- package/dist/lib/generated/Entities/APIScope/apiscope.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/Action/action.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/Action/action.form.component.js +44 -26
- package/dist/lib/generated/Entities/Action/action.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/ActionCategory/actioncategory.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/ActionCategory/actioncategory.form.component.js +23 -5
- package/dist/lib/generated/Entities/ActionCategory/actioncategory.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/Company/company.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/Company/company.form.component.js +28 -10
- package/dist/lib/generated/Entities/Company/company.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/Conversation/conversation.form.component.js +3 -3
- package/dist/lib/generated/Entities/ConversationDetailArtifact/conversationdetailartifact.form.component.js +3 -3
- package/dist/lib/generated/Entities/ConversationDetailArtifact/conversationdetailartifact.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/ConversationDetailRating/conversationdetailrating.form.component.js +3 -3
- package/dist/lib/generated/Entities/ConversationDetailRating/conversationdetailrating.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/Credential/credential.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/Credential/credential.form.component.js +23 -5
- package/dist/lib/generated/Entities/Credential/credential.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/CredentialType/credentialtype.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/CredentialType/credentialtype.form.component.js +23 -5
- package/dist/lib/generated/Entities/CredentialType/credentialtype.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/DuplicateRunDetail/duplicaterundetail.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/DuplicateRunDetail/duplicaterundetail.form.component.js +14 -20
- package/dist/lib/generated/Entities/DuplicateRunDetail/duplicaterundetail.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EmployeeCompanyIntegration/employeecompanyintegration.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/EmployeeCompanyIntegration/employeecompanyintegration.form.component.js +9 -15
- package/dist/lib/generated/Entities/EmployeeCompanyIntegration/employeecompanyintegration.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EmployeeRole/employeerole.form.component.js +3 -3
- package/dist/lib/generated/Entities/EmployeeRole/employeerole.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EmployeeSkill/employeeskill.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/EmployeeSkill/employeeskill.form.component.js +6 -12
- package/dist/lib/generated/Entities/EmployeeSkill/employeeskill.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/Entity/entity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/Entity/entity.form.component.js +110 -56
- package/dist/lib/generated/Entities/Entity/entity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EntityActionFilter/entityactionfilter.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/EntityActionFilter/entityactionfilter.form.component.js +5 -11
- package/dist/lib/generated/Entities/EntityActionFilter/entityactionfilter.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EntityActionInvocation/entityactioninvocation.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/EntityActionInvocation/entityactioninvocation.form.component.js +8 -14
- package/dist/lib/generated/Entities/EntityActionInvocation/entityactioninvocation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EntityActionParam/entityactionparam.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/EntityActionParam/entityactionparam.form.component.js +6 -12
- package/dist/lib/generated/Entities/EntityActionParam/entityactionparam.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/EntityCommunicationField/entitycommunicationfield.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/EntityCommunicationField/entitycommunicationfield.form.component.js +6 -12
- package/dist/lib/generated/Entities/EntityCommunicationField/entitycommunicationfield.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/ErrorLog/errorlog.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/ErrorLog/errorlog.form.component.js +11 -17
- package/dist/lib/generated/Entities/ErrorLog/errorlog.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MCPServer/mcpserver.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/MCPServer/mcpserver.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MCPServer/mcpserver.form.component.js +142 -0
- package/dist/lib/generated/Entities/MCPServer/mcpserver.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MCPServerConnection/mcpserverconnection.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/MCPServerConnection/mcpserverconnection.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MCPServerConnection/mcpserverconnection.form.component.js +158 -0
- package/dist/lib/generated/Entities/MCPServerConnection/mcpserverconnection.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MCPServerConnectionPermission/mcpserverconnectionpermission.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/MCPServerConnectionPermission/mcpserverconnectionpermission.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MCPServerConnectionPermission/mcpserverconnectionpermission.form.component.js +77 -0
- package/dist/lib/generated/Entities/MCPServerConnectionPermission/mcpserverconnectionpermission.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MCPServerConnectionTool/mcpserverconnectiontool.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/MCPServerConnectionTool/mcpserverconnectiontool.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MCPServerConnectionTool/mcpserverconnectiontool.form.component.js +73 -0
- package/dist/lib/generated/Entities/MCPServerConnectionTool/mcpserverconnectiontool.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MCPServerTool/mcpservertool.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/MCPServerTool/mcpservertool.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MCPServerTool/mcpservertool.form.component.js +132 -0
- package/dist/lib/generated/Entities/MCPServerTool/mcpservertool.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MCPToolExecutionLog/mcptoolexecutionlog.form.component.d.ts +11 -0
- package/dist/lib/generated/Entities/MCPToolExecutionLog/mcptoolexecutionlog.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MCPToolExecutionLog/mcptoolexecutionlog.form.component.js +101 -0
- package/dist/lib/generated/Entities/MCPToolExecutionLog/mcptoolexecutionlog.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/Role/role.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/Role/role.form.component.js +30 -12
- package/dist/lib/generated/Entities/Role/role.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/Task/task.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/Task/task.form.component.js +26 -32
- package/dist/lib/generated/Entities/Task/task.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/User/user.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/User/user.form.component.js +182 -146
- package/dist/lib/generated/Entities/User/user.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +142 -128
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +194 -101
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +30 -30
- package/dist/lib/custom/Actions/action-param-dialog.component.d.ts +0 -32
- package/dist/lib/custom/Actions/action-param-dialog.component.d.ts.map +0 -1
- package/dist/lib/custom/Actions/action-param-dialog.component.js +0 -321
- package/dist/lib/custom/Actions/action-param-dialog.component.js.map +0 -1
- package/dist/lib/custom/Actions/action-result-code-dialog.component.d.ts +0 -20
- package/dist/lib/custom/Actions/action-result-code-dialog.component.d.ts.map +0 -1
- package/dist/lib/custom/Actions/action-result-code-dialog.component.js +0 -127
- package/dist/lib/custom/Actions/action-result-code-dialog.component.js.map +0 -1
- package/dist/lib/custom/Actions/action-test-harness-dialog.component.d.ts +0 -15
- package/dist/lib/custom/Actions/action-test-harness-dialog.component.d.ts.map +0 -1
- package/dist/lib/custom/Actions/action-test-harness-dialog.component.js +0 -96
- package/dist/lib/custom/Actions/action-test-harness-dialog.component.js.map +0 -1
- package/dist/lib/custom/Actions/action-test-harness.component.d.ts +0 -50
- package/dist/lib/custom/Actions/action-test-harness.component.d.ts.map +0 -1
- package/dist/lib/custom/Actions/action-test-harness.component.js +0 -710
- package/dist/lib/custom/Actions/action-test-harness.component.js.map +0 -1
|
@@ -19,18 +19,19 @@ import * as i0 from "@angular/core";
|
|
|
19
19
|
import * as i1 from "@memberjunction/ng-shared";
|
|
20
20
|
import * as i2 from "@angular/router";
|
|
21
21
|
import * as i3 from "@memberjunction/ng-testing";
|
|
22
|
-
import * as i4 from "@
|
|
23
|
-
import * as i5 from "@angular/
|
|
24
|
-
import * as i6 from "@
|
|
25
|
-
import * as i7 from "@progress/kendo-angular-
|
|
26
|
-
import * as i8 from "@
|
|
27
|
-
import * as i9 from "@memberjunction/ng-
|
|
28
|
-
import * as i10 from "
|
|
22
|
+
import * as i4 from "@memberjunction/ng-base-application";
|
|
23
|
+
import * as i5 from "@angular/common";
|
|
24
|
+
import * as i6 from "@angular/forms";
|
|
25
|
+
import * as i7 from "@progress/kendo-angular-dialog";
|
|
26
|
+
import * as i8 from "@progress/kendo-angular-buttons";
|
|
27
|
+
import * as i9 from "@memberjunction/ng-code-editor";
|
|
28
|
+
import * as i10 from "@memberjunction/ng-shared-generic";
|
|
29
|
+
import * as i11 from "./entity-link-pill.component";
|
|
29
30
|
const _c0 = () => [1, 2, 3, 4, 5];
|
|
30
31
|
const _c1 = () => [1, 2, 3];
|
|
31
|
-
function
|
|
32
|
-
i0.ɵɵelementStart(0, "span",
|
|
33
|
-
i0.ɵɵelement(1, "i",
|
|
32
|
+
function TestFormComponentExtended_span_25_Template(rf, ctx) { if (rf & 1) {
|
|
33
|
+
i0.ɵɵelementStart(0, "span", 41);
|
|
34
|
+
i0.ɵɵelement(1, "i", 42);
|
|
34
35
|
i0.ɵɵtext(2);
|
|
35
36
|
i0.ɵɵelementEnd();
|
|
36
37
|
} if (rf & 2) {
|
|
@@ -38,8 +39,8 @@ function TestFormComponentExtended_span_13_Template(rf, ctx) { if (rf & 1) {
|
|
|
38
39
|
i0.ɵɵadvance(2);
|
|
39
40
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.record.Type, " ");
|
|
40
41
|
} }
|
|
41
|
-
function
|
|
42
|
-
i0.ɵɵelementStart(0, "div",
|
|
42
|
+
function TestFormComponentExtended_div_34_Template(rf, ctx) { if (rf & 1) {
|
|
43
|
+
i0.ɵɵelementStart(0, "div", 43)(1, "p");
|
|
43
44
|
i0.ɵɵtext(2);
|
|
44
45
|
i0.ɵɵelementEnd()();
|
|
45
46
|
} if (rf & 2) {
|
|
@@ -47,32 +48,32 @@ function TestFormComponentExtended_div_22_Template(rf, ctx) { if (rf & 1) {
|
|
|
47
48
|
i0.ɵɵadvance(2);
|
|
48
49
|
i0.ɵɵtextInterpolate(ctx_r0.record.Description);
|
|
49
50
|
} }
|
|
50
|
-
function
|
|
51
|
-
i0.ɵɵelementStart(0, "div",
|
|
51
|
+
function TestFormComponentExtended_div_35_Template(rf, ctx) { if (rf & 1) {
|
|
52
|
+
i0.ɵɵelementStart(0, "div", 44)(1, "div", 45)(2, "div", 46);
|
|
52
53
|
i0.ɵɵtext(3, "Total Runs");
|
|
53
54
|
i0.ɵɵelementEnd();
|
|
54
|
-
i0.ɵɵelementStart(4, "div",
|
|
55
|
+
i0.ɵɵelementStart(4, "div", 47);
|
|
55
56
|
i0.ɵɵtext(5);
|
|
56
57
|
i0.ɵɵelementEnd()();
|
|
57
|
-
i0.ɵɵelementStart(6, "div",
|
|
58
|
+
i0.ɵɵelementStart(6, "div", 45)(7, "div", 46);
|
|
58
59
|
i0.ɵɵtext(8, "Pass Rate");
|
|
59
60
|
i0.ɵɵelementEnd();
|
|
60
|
-
i0.ɵɵelementStart(9, "div",
|
|
61
|
+
i0.ɵɵelementStart(9, "div", 47);
|
|
61
62
|
i0.ɵɵtext(10);
|
|
62
63
|
i0.ɵɵelementEnd();
|
|
63
|
-
i0.ɵɵelementStart(11, "div",
|
|
64
|
-
i0.ɵɵelement(12, "div",
|
|
64
|
+
i0.ɵɵelementStart(11, "div", 48);
|
|
65
|
+
i0.ɵɵelement(12, "div", 49);
|
|
65
66
|
i0.ɵɵelementEnd()();
|
|
66
|
-
i0.ɵɵelementStart(13, "div",
|
|
67
|
+
i0.ɵɵelementStart(13, "div", 45)(14, "div", 46);
|
|
67
68
|
i0.ɵɵtext(15, "Avg Cost");
|
|
68
69
|
i0.ɵɵelementEnd();
|
|
69
|
-
i0.ɵɵelementStart(16, "div",
|
|
70
|
+
i0.ɵɵelementStart(16, "div", 47);
|
|
70
71
|
i0.ɵɵtext(17);
|
|
71
72
|
i0.ɵɵelementEnd()();
|
|
72
|
-
i0.ɵɵelementStart(18, "div",
|
|
73
|
+
i0.ɵɵelementStart(18, "div", 45)(19, "div", 46);
|
|
73
74
|
i0.ɵɵtext(20, "Avg Duration");
|
|
74
75
|
i0.ɵɵelementEnd();
|
|
75
|
-
i0.ɵɵelementStart(21, "div",
|
|
76
|
+
i0.ɵɵelementStart(21, "div", 47);
|
|
76
77
|
i0.ɵɵtext(22);
|
|
77
78
|
i0.ɵɵelementEnd()()();
|
|
78
79
|
} if (rf & 2) {
|
|
@@ -88,8 +89,8 @@ function TestFormComponentExtended_div_23_Template(rf, ctx) { if (rf & 1) {
|
|
|
88
89
|
i0.ɵɵadvance(5);
|
|
89
90
|
i0.ɵɵtextInterpolate(ctx_r0.formatDuration(ctx_r0.getAverageDuration()));
|
|
90
91
|
} }
|
|
91
|
-
function
|
|
92
|
-
i0.ɵɵelementStart(0, "span",
|
|
92
|
+
function TestFormComponentExtended_span_50_Template(rf, ctx) { if (rf & 1) {
|
|
93
|
+
i0.ɵɵelementStart(0, "span", 50);
|
|
93
94
|
i0.ɵɵtext(1);
|
|
94
95
|
i0.ɵɵelementEnd();
|
|
95
96
|
} if (rf & 2) {
|
|
@@ -97,8 +98,8 @@ function TestFormComponentExtended_span_38_Template(rf, ctx) { if (rf & 1) {
|
|
|
97
98
|
i0.ɵɵadvance();
|
|
98
99
|
i0.ɵɵtextInterpolate(ctx_r0.testRuns.length);
|
|
99
100
|
} }
|
|
100
|
-
function
|
|
101
|
-
i0.ɵɵelementStart(0, "span",
|
|
101
|
+
function TestFormComponentExtended_span_55_Template(rf, ctx) { if (rf & 1) {
|
|
102
|
+
i0.ɵɵelementStart(0, "span", 50);
|
|
102
103
|
i0.ɵɵtext(1);
|
|
103
104
|
i0.ɵɵelementEnd();
|
|
104
105
|
} if (rf & 2) {
|
|
@@ -106,100 +107,100 @@ function TestFormComponentExtended_span_43_Template(rf, ctx) { if (rf & 1) {
|
|
|
106
107
|
i0.ɵɵadvance();
|
|
107
108
|
i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
|
|
108
109
|
} }
|
|
109
|
-
function
|
|
110
|
+
function TestFormComponentExtended_div_61_Template(rf, ctx) { if (rf & 1) {
|
|
110
111
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
111
|
-
i0.ɵɵelementStart(0, "div",
|
|
112
|
-
i0.ɵɵelement(3, "i",
|
|
112
|
+
i0.ɵɵelementStart(0, "div", 51)(1, "div", 52)(2, "h3");
|
|
113
|
+
i0.ɵɵelement(3, "i", 53);
|
|
113
114
|
i0.ɵɵtext(4, " Test Information");
|
|
114
115
|
i0.ɵɵelementEnd();
|
|
115
|
-
i0.ɵɵelementStart(5, "div",
|
|
116
|
+
i0.ɵɵelementStart(5, "div", 54)(6, "div", 55)(7, "div", 56);
|
|
116
117
|
i0.ɵɵtext(8, "Name");
|
|
117
118
|
i0.ɵɵelementEnd();
|
|
118
|
-
i0.ɵɵelementStart(9, "div",
|
|
119
|
+
i0.ɵɵelementStart(9, "div", 57);
|
|
119
120
|
i0.ɵɵtext(10);
|
|
120
121
|
i0.ɵɵelementEnd()();
|
|
121
|
-
i0.ɵɵelementStart(11, "div",
|
|
122
|
+
i0.ɵɵelementStart(11, "div", 55)(12, "div", 56);
|
|
122
123
|
i0.ɵɵtext(13, "Type");
|
|
123
124
|
i0.ɵɵelementEnd();
|
|
124
|
-
i0.ɵɵelementStart(14, "div",
|
|
125
|
+
i0.ɵɵelementStart(14, "div", 57);
|
|
125
126
|
i0.ɵɵtext(15);
|
|
126
127
|
i0.ɵɵelementEnd()();
|
|
127
|
-
i0.ɵɵelementStart(16, "div",
|
|
128
|
+
i0.ɵɵelementStart(16, "div", 55)(17, "div", 56);
|
|
128
129
|
i0.ɵɵtext(18, "Status");
|
|
129
130
|
i0.ɵɵelementEnd();
|
|
130
|
-
i0.ɵɵelementStart(19, "div",
|
|
131
|
+
i0.ɵɵelementStart(19, "div", 57)(20, "span", 58);
|
|
131
132
|
i0.ɵɵtext(21);
|
|
132
133
|
i0.ɵɵelementEnd()()();
|
|
133
|
-
i0.ɵɵelementStart(22, "div",
|
|
134
|
+
i0.ɵɵelementStart(22, "div", 55)(23, "div", 56);
|
|
134
135
|
i0.ɵɵtext(24, "Priority");
|
|
135
136
|
i0.ɵɵelementEnd();
|
|
136
|
-
i0.ɵɵelementStart(25, "div",
|
|
137
|
+
i0.ɵɵelementStart(25, "div", 57);
|
|
137
138
|
i0.ɵɵtext(26);
|
|
138
139
|
i0.ɵɵelementEnd()();
|
|
139
|
-
i0.ɵɵelementStart(27, "div",
|
|
140
|
+
i0.ɵɵelementStart(27, "div", 55)(28, "div", 56);
|
|
140
141
|
i0.ɵɵtext(29, "Estimated Duration");
|
|
141
142
|
i0.ɵɵelementEnd();
|
|
142
|
-
i0.ɵɵelementStart(30, "div",
|
|
143
|
+
i0.ɵɵelementStart(30, "div", 57);
|
|
143
144
|
i0.ɵɵtext(31);
|
|
144
145
|
i0.ɵɵelementEnd()();
|
|
145
|
-
i0.ɵɵelementStart(32, "div",
|
|
146
|
+
i0.ɵɵelementStart(32, "div", 55)(33, "div", 56);
|
|
146
147
|
i0.ɵɵtext(34, "Estimated Cost");
|
|
147
148
|
i0.ɵɵelementEnd();
|
|
148
|
-
i0.ɵɵelementStart(35, "div",
|
|
149
|
+
i0.ɵɵelementStart(35, "div", 57);
|
|
149
150
|
i0.ɵɵtext(36);
|
|
150
151
|
i0.ɵɵelementEnd()();
|
|
151
|
-
i0.ɵɵelementStart(37, "div",
|
|
152
|
+
i0.ɵɵelementStart(37, "div", 55)(38, "div", 56);
|
|
152
153
|
i0.ɵɵtext(39, "Repeat Count");
|
|
153
154
|
i0.ɵɵelementEnd();
|
|
154
|
-
i0.ɵɵelementStart(40, "div",
|
|
155
|
+
i0.ɵɵelementStart(40, "div", 57);
|
|
155
156
|
i0.ɵɵtext(41);
|
|
156
157
|
i0.ɵɵelementEnd()();
|
|
157
|
-
i0.ɵɵelementStart(42, "div",
|
|
158
|
+
i0.ɵɵelementStart(42, "div", 55)(43, "div", 56);
|
|
158
159
|
i0.ɵɵtext(44, "Max Execution Time");
|
|
159
160
|
i0.ɵɵelementEnd();
|
|
160
|
-
i0.ɵɵelementStart(45, "div",
|
|
161
|
+
i0.ɵɵelementStart(45, "div", 57);
|
|
161
162
|
i0.ɵɵtext(46);
|
|
162
163
|
i0.ɵɵelementEnd()();
|
|
163
|
-
i0.ɵɵelementStart(47, "div",
|
|
164
|
+
i0.ɵɵelementStart(47, "div", 55)(48, "div", 56);
|
|
164
165
|
i0.ɵɵtext(49, "Created");
|
|
165
166
|
i0.ɵɵelementEnd();
|
|
166
|
-
i0.ɵɵelementStart(50, "div",
|
|
167
|
+
i0.ɵɵelementStart(50, "div", 57);
|
|
167
168
|
i0.ɵɵtext(51);
|
|
168
169
|
i0.ɵɵpipe(52, "date");
|
|
169
170
|
i0.ɵɵelementEnd()();
|
|
170
|
-
i0.ɵɵelementStart(53, "div",
|
|
171
|
+
i0.ɵɵelementStart(53, "div", 55)(54, "div", 56);
|
|
171
172
|
i0.ɵɵtext(55, "Updated");
|
|
172
173
|
i0.ɵɵelementEnd();
|
|
173
|
-
i0.ɵɵelementStart(56, "div",
|
|
174
|
+
i0.ɵɵelementStart(56, "div", 57);
|
|
174
175
|
i0.ɵɵtext(57);
|
|
175
176
|
i0.ɵɵpipe(58, "date");
|
|
176
177
|
i0.ɵɵelementEnd()()()();
|
|
177
|
-
i0.ɵɵelementStart(59, "div",
|
|
178
|
-
i0.ɵɵelement(61, "i",
|
|
178
|
+
i0.ɵɵelementStart(59, "div", 59)(60, "h3");
|
|
179
|
+
i0.ɵɵelement(61, "i", 60);
|
|
179
180
|
i0.ɵɵtext(62, " Test Definition");
|
|
180
181
|
i0.ɵɵelementEnd();
|
|
181
|
-
i0.ɵɵelementStart(63, "div",
|
|
182
|
-
i0.ɵɵlistener("click", function
|
|
183
|
-
i0.ɵɵelement(65, "i",
|
|
182
|
+
i0.ɵɵelementStart(63, "div", 61)(64, "button", 62);
|
|
183
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_61_Template_button_click_64_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("input")); });
|
|
184
|
+
i0.ɵɵelement(65, "i", 63);
|
|
184
185
|
i0.ɵɵtext(66, " Input Definition ");
|
|
185
186
|
i0.ɵɵelementEnd();
|
|
186
|
-
i0.ɵɵelementStart(67, "button",
|
|
187
|
-
i0.ɵɵlistener("click", function
|
|
188
|
-
i0.ɵɵelement(68, "i",
|
|
187
|
+
i0.ɵɵelementStart(67, "button", 62);
|
|
188
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_61_Template_button_click_67_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("expected")); });
|
|
189
|
+
i0.ɵɵelement(68, "i", 64);
|
|
189
190
|
i0.ɵɵtext(69, " Expected Outcomes ");
|
|
190
191
|
i0.ɵɵelementEnd();
|
|
191
|
-
i0.ɵɵelementStart(70, "button",
|
|
192
|
-
i0.ɵɵlistener("click", function
|
|
193
|
-
i0.ɵɵelement(71, "i",
|
|
192
|
+
i0.ɵɵelementStart(70, "button", 62);
|
|
193
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_61_Template_button_click_70_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("config")); });
|
|
194
|
+
i0.ɵɵelement(71, "i", 65);
|
|
194
195
|
i0.ɵɵtext(72, " Configuration ");
|
|
195
196
|
i0.ɵɵelementEnd();
|
|
196
|
-
i0.ɵɵelementStart(73, "button",
|
|
197
|
-
i0.ɵɵlistener("click", function
|
|
198
|
-
i0.ɵɵelement(74, "i",
|
|
197
|
+
i0.ɵɵelementStart(73, "button", 62);
|
|
198
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_61_Template_button_click_73_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.setJsonView("tags")); });
|
|
199
|
+
i0.ɵɵelement(74, "i", 66);
|
|
199
200
|
i0.ɵɵtext(75, " Tags ");
|
|
200
201
|
i0.ɵɵelementEnd()();
|
|
201
|
-
i0.ɵɵelementStart(76, "div",
|
|
202
|
-
i0.ɵɵelement(77, "mj-code-editor",
|
|
202
|
+
i0.ɵɵelementStart(76, "div", 67);
|
|
203
|
+
i0.ɵɵelement(77, "mj-code-editor", 68);
|
|
203
204
|
i0.ɵɵelementEnd()()();
|
|
204
205
|
} if (rf & 2) {
|
|
205
206
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -236,72 +237,72 @@ function TestFormComponentExtended_div_49_Template(rf, ctx) { if (rf & 1) {
|
|
|
236
237
|
i0.ɵɵadvance(4);
|
|
237
238
|
i0.ɵɵproperty("value", ctx_r0.getJsonData())("readonly", true)("toolbar", ctx_r0.jsonToolbar)("lineWrapping", true);
|
|
238
239
|
} }
|
|
239
|
-
function
|
|
240
|
+
function TestFormComponentExtended_div_62_Template(rf, ctx) { if (rf & 1) {
|
|
240
241
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
241
|
-
i0.ɵɵelementStart(0, "div",
|
|
242
|
-
i0.ɵɵelement(3, "i",
|
|
242
|
+
i0.ɵɵelementStart(0, "div", 69)(1, "div", 70)(2, "h3");
|
|
243
|
+
i0.ɵɵelement(3, "i", 71);
|
|
243
244
|
i0.ɵɵtext(4, " Execution Settings");
|
|
244
245
|
i0.ɵɵelementEnd();
|
|
245
|
-
i0.ɵɵelementStart(5, "div",
|
|
246
|
+
i0.ɵɵelementStart(5, "div", 72)(6, "div", 73)(7, "label");
|
|
246
247
|
i0.ɵɵtext(8, "Priority");
|
|
247
248
|
i0.ɵɵelementEnd();
|
|
248
|
-
i0.ɵɵelementStart(9, "input",
|
|
249
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
249
|
+
i0.ɵɵelementStart(9, "input", 74);
|
|
250
|
+
i0.ɵɵtwoWayListener("ngModelChange", function TestFormComponentExtended_div_62_Template_input_ngModelChange_9_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.Priority, $event) || (ctx_r0.record.Priority = $event); return i0.ɵɵresetView($event); });
|
|
250
251
|
i0.ɵɵelementEnd()();
|
|
251
|
-
i0.ɵɵelementStart(10, "div",
|
|
252
|
+
i0.ɵɵelementStart(10, "div", 73)(11, "label");
|
|
252
253
|
i0.ɵɵtext(12, "Repeat Count");
|
|
253
254
|
i0.ɵɵelementEnd();
|
|
254
|
-
i0.ɵɵelementStart(13, "input",
|
|
255
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
255
|
+
i0.ɵɵelementStart(13, "input", 75);
|
|
256
|
+
i0.ɵɵtwoWayListener("ngModelChange", function TestFormComponentExtended_div_62_Template_input_ngModelChange_13_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.RepeatCount, $event) || (ctx_r0.record.RepeatCount = $event); return i0.ɵɵresetView($event); });
|
|
256
257
|
i0.ɵɵelementEnd()();
|
|
257
|
-
i0.ɵɵelementStart(14, "div",
|
|
258
|
+
i0.ɵɵelementStart(14, "div", 73)(15, "label");
|
|
258
259
|
i0.ɵɵtext(16, "Estimated Duration (seconds)");
|
|
259
260
|
i0.ɵɵelementEnd();
|
|
260
|
-
i0.ɵɵelementStart(17, "input",
|
|
261
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
261
|
+
i0.ɵɵelementStart(17, "input", 76);
|
|
262
|
+
i0.ɵɵtwoWayListener("ngModelChange", function TestFormComponentExtended_div_62_Template_input_ngModelChange_17_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.EstimatedDurationSeconds, $event) || (ctx_r0.record.EstimatedDurationSeconds = $event); return i0.ɵɵresetView($event); });
|
|
262
263
|
i0.ɵɵelementEnd()();
|
|
263
|
-
i0.ɵɵelementStart(18, "div",
|
|
264
|
+
i0.ɵɵelementStart(18, "div", 73)(19, "label");
|
|
264
265
|
i0.ɵɵtext(20, "Estimated Cost (USD)");
|
|
265
266
|
i0.ɵɵelementEnd();
|
|
266
|
-
i0.ɵɵelementStart(21, "input",
|
|
267
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
267
|
+
i0.ɵɵelementStart(21, "input", 77);
|
|
268
|
+
i0.ɵɵtwoWayListener("ngModelChange", function TestFormComponentExtended_div_62_Template_input_ngModelChange_21_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.EstimatedCostUSD, $event) || (ctx_r0.record.EstimatedCostUSD = $event); return i0.ɵɵresetView($event); });
|
|
268
269
|
i0.ɵɵelementEnd()();
|
|
269
|
-
i0.ɵɵelementStart(22, "div",
|
|
270
|
+
i0.ɵɵelementStart(22, "div", 78)(23, "label");
|
|
270
271
|
i0.ɵɵtext(24, "Max Execution Time (ms)");
|
|
271
272
|
i0.ɵɵelementEnd();
|
|
272
|
-
i0.ɵɵelementStart(25, "input",
|
|
273
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
273
|
+
i0.ɵɵelementStart(25, "input", 79);
|
|
274
|
+
i0.ɵɵtwoWayListener("ngModelChange", function TestFormComponentExtended_div_62_Template_input_ngModelChange_25_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.MaxExecutionTimeMS, $event) || (ctx_r0.record.MaxExecutionTimeMS = $event); return i0.ɵɵresetView($event); });
|
|
274
275
|
i0.ɵɵelementEnd();
|
|
275
|
-
i0.ɵɵelementStart(26, "span",
|
|
276
|
+
i0.ɵɵelementStart(26, "span", 80);
|
|
276
277
|
i0.ɵɵtext(27, "Leave empty for default 5 minute timeout");
|
|
277
278
|
i0.ɵɵelementEnd()()()();
|
|
278
|
-
i0.ɵɵelementStart(28, "div",
|
|
279
|
-
i0.ɵɵelement(30, "i",
|
|
279
|
+
i0.ɵɵelementStart(28, "div", 70)(29, "h3");
|
|
280
|
+
i0.ɵɵelement(30, "i", 63);
|
|
280
281
|
i0.ɵɵtext(31, " Input Definition (JSON)");
|
|
281
282
|
i0.ɵɵelementEnd();
|
|
282
|
-
i0.ɵɵelementStart(32, "div",
|
|
283
|
-
i0.ɵɵlistener("change", function
|
|
283
|
+
i0.ɵɵelementStart(32, "div", 81)(33, "mj-code-editor", 82);
|
|
284
|
+
i0.ɵɵlistener("change", function TestFormComponentExtended_div_62_Template_mj_code_editor_change_33_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.InputDefinition = $event); });
|
|
284
285
|
i0.ɵɵelementEnd()()();
|
|
285
|
-
i0.ɵɵelementStart(34, "div",
|
|
286
|
-
i0.ɵɵelement(36, "i",
|
|
286
|
+
i0.ɵɵelementStart(34, "div", 70)(35, "h3");
|
|
287
|
+
i0.ɵɵelement(36, "i", 64);
|
|
287
288
|
i0.ɵɵtext(37, " Expected Outcomes (JSON)");
|
|
288
289
|
i0.ɵɵelementEnd();
|
|
289
|
-
i0.ɵɵelementStart(38, "div",
|
|
290
|
-
i0.ɵɵlistener("change", function
|
|
290
|
+
i0.ɵɵelementStart(38, "div", 81)(39, "mj-code-editor", 82);
|
|
291
|
+
i0.ɵɵlistener("change", function TestFormComponentExtended_div_62_Template_mj_code_editor_change_39_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.ExpectedOutcomes = $event); });
|
|
291
292
|
i0.ɵɵelementEnd()()();
|
|
292
|
-
i0.ɵɵelementStart(40, "div",
|
|
293
|
-
i0.ɵɵelement(42, "i",
|
|
293
|
+
i0.ɵɵelementStart(40, "div", 70)(41, "h3");
|
|
294
|
+
i0.ɵɵelement(42, "i", 65);
|
|
294
295
|
i0.ɵɵtext(43, " Configuration (JSON)");
|
|
295
296
|
i0.ɵɵelementEnd();
|
|
296
|
-
i0.ɵɵelementStart(44, "div",
|
|
297
|
-
i0.ɵɵlistener("change", function
|
|
297
|
+
i0.ɵɵelementStart(44, "div", 81)(45, "mj-code-editor", 82);
|
|
298
|
+
i0.ɵɵlistener("change", function TestFormComponentExtended_div_62_Template_mj_code_editor_change_45_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Configuration = $event); });
|
|
298
299
|
i0.ɵɵelementEnd()()();
|
|
299
|
-
i0.ɵɵelementStart(46, "div",
|
|
300
|
-
i0.ɵɵelement(48, "i",
|
|
300
|
+
i0.ɵɵelementStart(46, "div", 70)(47, "h3");
|
|
301
|
+
i0.ɵɵelement(48, "i", 66);
|
|
301
302
|
i0.ɵɵtext(49, " Tags (JSON Array)");
|
|
302
303
|
i0.ɵɵelementEnd();
|
|
303
|
-
i0.ɵɵelementStart(50, "div",
|
|
304
|
-
i0.ɵɵlistener("change", function
|
|
304
|
+
i0.ɵɵelementStart(50, "div", 83)(51, "mj-code-editor", 82);
|
|
305
|
+
i0.ɵɵlistener("change", function TestFormComponentExtended_div_62_Template_mj_code_editor_change_51_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.record.Tags = $event); });
|
|
305
306
|
i0.ɵɵelementEnd()()()();
|
|
306
307
|
} if (rf & 2) {
|
|
307
308
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -324,24 +325,24 @@ function TestFormComponentExtended_div_50_Template(rf, ctx) { if (rf & 1) {
|
|
|
324
325
|
i0.ɵɵadvance(6);
|
|
325
326
|
i0.ɵɵproperty("value", ctx_r0.record.Tags || "[]")("readonly", false)("lineWrapping", true);
|
|
326
327
|
} }
|
|
327
|
-
function
|
|
328
|
-
i0.ɵɵelementStart(0, "div",
|
|
329
|
-
i0.ɵɵelement(1, "div",
|
|
330
|
-
i0.ɵɵelementStart(2, "div",
|
|
331
|
-
i0.ɵɵelement(3, "div",
|
|
328
|
+
function TestFormComponentExtended_div_63_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
329
|
+
i0.ɵɵelementStart(0, "div", 91);
|
|
330
|
+
i0.ɵɵelement(1, "div", 92);
|
|
331
|
+
i0.ɵɵelementStart(2, "div", 93);
|
|
332
|
+
i0.ɵɵelement(3, "div", 94)(4, "div", 95);
|
|
332
333
|
i0.ɵɵelementEnd()();
|
|
333
334
|
} }
|
|
334
|
-
function
|
|
335
|
-
i0.ɵɵelementStart(0, "div",
|
|
336
|
-
i0.ɵɵtemplate(2,
|
|
335
|
+
function TestFormComponentExtended_div_63_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
336
|
+
i0.ɵɵelementStart(0, "div", 88)(1, "div", 89);
|
|
337
|
+
i0.ɵɵtemplate(2, TestFormComponentExtended_div_63_div_1_div_2_Template, 5, 0, "div", 90);
|
|
337
338
|
i0.ɵɵelementEnd()();
|
|
338
339
|
} if (rf & 2) {
|
|
339
340
|
i0.ɵɵadvance(2);
|
|
340
341
|
i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c0));
|
|
341
342
|
} }
|
|
342
|
-
function
|
|
343
|
+
function TestFormComponentExtended_div_63_div_2_div_1_span_13_Template(rf, ctx) { if (rf & 1) {
|
|
343
344
|
i0.ɵɵelementStart(0, "span");
|
|
344
|
-
i0.ɵɵelement(1, "i",
|
|
345
|
+
i0.ɵɵelement(1, "i", 113);
|
|
345
346
|
i0.ɵɵtext(2);
|
|
346
347
|
i0.ɵɵelementEnd();
|
|
347
348
|
} if (rf & 2) {
|
|
@@ -350,9 +351,9 @@ function TestFormComponentExtended_div_51_div_2_div_1_span_13_Template(rf, ctx)
|
|
|
350
351
|
i0.ɵɵadvance(2);
|
|
351
352
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.formatDuration(run_r5.DurationSeconds), "");
|
|
352
353
|
} }
|
|
353
|
-
function
|
|
354
|
+
function TestFormComponentExtended_div_63_div_2_div_1_span_14_Template(rf, ctx) { if (rf & 1) {
|
|
354
355
|
i0.ɵɵelementStart(0, "span");
|
|
355
|
-
i0.ɵɵelement(1, "i",
|
|
356
|
+
i0.ɵɵelement(1, "i", 114);
|
|
356
357
|
i0.ɵɵtext(2);
|
|
357
358
|
i0.ɵɵelementEnd();
|
|
358
359
|
} if (rf & 2) {
|
|
@@ -361,15 +362,15 @@ function TestFormComponentExtended_div_51_div_2_div_1_span_14_Template(rf, ctx)
|
|
|
361
362
|
i0.ɵɵadvance(2);
|
|
362
363
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.formatCost(run_r5.CostUSD), "");
|
|
363
364
|
} }
|
|
364
|
-
function
|
|
365
|
-
i0.ɵɵelement(0, "mj-entity-link-pill",
|
|
365
|
+
function TestFormComponentExtended_div_63_div_2_div_1_mj_entity_link_pill_15_Template(rf, ctx) { if (rf & 1) {
|
|
366
|
+
i0.ɵɵelement(0, "mj-entity-link-pill", 115);
|
|
366
367
|
} if (rf & 2) {
|
|
367
368
|
const run_r5 = i0.ɵɵnextContext().$implicit;
|
|
368
369
|
i0.ɵɵproperty("entityName", run_r5.TargetLogEntity)("recordId", run_r5.TargetLogID);
|
|
369
370
|
} }
|
|
370
|
-
function
|
|
371
|
-
i0.ɵɵelementStart(0, "span",
|
|
372
|
-
i0.ɵɵelement(1, "i",
|
|
371
|
+
function TestFormComponentExtended_div_63_div_2_div_1_span_17_Template(rf, ctx) { if (rf & 1) {
|
|
372
|
+
i0.ɵɵelementStart(0, "span", 116);
|
|
373
|
+
i0.ɵɵelement(1, "i", 100);
|
|
373
374
|
i0.ɵɵelementStart(2, "span");
|
|
374
375
|
i0.ɵɵtext(3);
|
|
375
376
|
i0.ɵɵelementEnd()();
|
|
@@ -382,14 +383,14 @@ function TestFormComponentExtended_div_51_div_2_div_1_span_17_Template(rf, ctx)
|
|
|
382
383
|
i0.ɵɵadvance(2);
|
|
383
384
|
i0.ɵɵtextInterpolate(run_r5.Status);
|
|
384
385
|
} }
|
|
385
|
-
function
|
|
386
|
-
i0.ɵɵelementStart(0, "span",
|
|
387
|
-
i0.ɵɵelement(1, "i",
|
|
386
|
+
function TestFormComponentExtended_div_63_div_2_div_1_ng_container_18_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
387
|
+
i0.ɵɵelementStart(0, "span", 119);
|
|
388
|
+
i0.ɵɵelement(1, "i", 120);
|
|
388
389
|
i0.ɵɵelementEnd();
|
|
389
390
|
} }
|
|
390
|
-
function
|
|
391
|
-
i0.ɵɵelementStart(0, "span",
|
|
392
|
-
i0.ɵɵelement(1, "i",
|
|
391
|
+
function TestFormComponentExtended_div_63_div_2_div_1_ng_container_18_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
392
|
+
i0.ɵɵelementStart(0, "span", 121);
|
|
393
|
+
i0.ɵɵelement(1, "i", 122);
|
|
393
394
|
i0.ɵɵelementStart(2, "span");
|
|
394
395
|
i0.ɵɵtext(3);
|
|
395
396
|
i0.ɵɵelementEnd()();
|
|
@@ -403,9 +404,9 @@ function TestFormComponentExtended_div_51_div_2_div_1_ng_container_18_span_2_Tem
|
|
|
403
404
|
i0.ɵɵadvance(3);
|
|
404
405
|
i0.ɵɵtextInterpolate(rating_r6);
|
|
405
406
|
} }
|
|
406
|
-
function
|
|
407
|
+
function TestFormComponentExtended_div_63_div_2_div_1_ng_container_18_Template(rf, ctx) { if (rf & 1) {
|
|
407
408
|
i0.ɵɵelementContainerStart(0);
|
|
408
|
-
i0.ɵɵtemplate(1,
|
|
409
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_63_div_2_div_1_ng_container_18_span_1_Template, 2, 0, "span", 117)(2, TestFormComponentExtended_div_63_div_2_div_1_ng_container_18_span_2_Template, 4, 10, "span", 118);
|
|
409
410
|
i0.ɵɵelementContainerEnd();
|
|
410
411
|
} if (rf & 2) {
|
|
411
412
|
let tmp_5_0;
|
|
@@ -417,14 +418,14 @@ function TestFormComponentExtended_div_51_div_2_div_1_ng_container_18_Template(r
|
|
|
417
418
|
i0.ɵɵadvance();
|
|
418
419
|
i0.ɵɵproperty("ngIf", (tmp_6_0 = ctx_r0.getFeedbackForRun(run_r5.ID)) == null ? null : tmp_6_0.Rating);
|
|
419
420
|
} }
|
|
420
|
-
function
|
|
421
|
-
i0.ɵɵelementStart(0, "span",
|
|
422
|
-
i0.ɵɵelement(1, "i",
|
|
421
|
+
function TestFormComponentExtended_div_63_div_2_div_1_ng_container_19_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
422
|
+
i0.ɵɵelementStart(0, "span", 125);
|
|
423
|
+
i0.ɵɵelement(1, "i", 126);
|
|
423
424
|
i0.ɵɵelementEnd();
|
|
424
425
|
} }
|
|
425
|
-
function
|
|
426
|
-
i0.ɵɵelementStart(0, "span",
|
|
427
|
-
i0.ɵɵelement(1, "i",
|
|
426
|
+
function TestFormComponentExtended_div_63_div_2_div_1_ng_container_19_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
427
|
+
i0.ɵɵelementStart(0, "span", 127);
|
|
428
|
+
i0.ɵɵelement(1, "i", 126);
|
|
428
429
|
i0.ɵɵelementStart(2, "span");
|
|
429
430
|
i0.ɵɵtext(3);
|
|
430
431
|
i0.ɵɵelementEnd()();
|
|
@@ -435,9 +436,9 @@ function TestFormComponentExtended_div_51_div_2_div_1_ng_container_19_span_2_Tem
|
|
|
435
436
|
i0.ɵɵadvance(3);
|
|
436
437
|
i0.ɵɵtextInterpolate1("", (run_r5.Score * 100).toFixed(0), "%");
|
|
437
438
|
} }
|
|
438
|
-
function
|
|
439
|
+
function TestFormComponentExtended_div_63_div_2_div_1_ng_container_19_Template(rf, ctx) { if (rf & 1) {
|
|
439
440
|
i0.ɵɵelementContainerStart(0);
|
|
440
|
-
i0.ɵɵtemplate(1,
|
|
441
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_63_div_2_div_1_ng_container_19_span_1_Template, 2, 0, "span", 123)(2, TestFormComponentExtended_div_63_div_2_div_1_ng_container_19_span_2_Template, 4, 10, "span", 124);
|
|
441
442
|
i0.ɵɵelementContainerEnd();
|
|
442
443
|
} if (rf & 2) {
|
|
443
444
|
const run_r5 = i0.ɵɵnextContext().$implicit;
|
|
@@ -446,8 +447,8 @@ function TestFormComponentExtended_div_51_div_2_div_1_ng_container_19_Template(r
|
|
|
446
447
|
i0.ɵɵadvance();
|
|
447
448
|
i0.ɵɵproperty("ngIf", run_r5.Score != null);
|
|
448
449
|
} }
|
|
449
|
-
function
|
|
450
|
-
i0.ɵɵelementStart(0, "span",
|
|
450
|
+
function TestFormComponentExtended_div_63_div_2_div_1_div_20_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
451
|
+
i0.ɵɵelementStart(0, "span", 131);
|
|
451
452
|
i0.ɵɵtext(1);
|
|
452
453
|
i0.ɵɵelementEnd();
|
|
453
454
|
} if (rf & 2) {
|
|
@@ -455,8 +456,8 @@ function TestFormComponentExtended_div_51_div_2_div_1_div_20_span_1_Template(rf,
|
|
|
455
456
|
i0.ɵɵadvance();
|
|
456
457
|
i0.ɵɵtextInterpolate(tag_r7);
|
|
457
458
|
} }
|
|
458
|
-
function
|
|
459
|
-
i0.ɵɵelementStart(0, "span",
|
|
459
|
+
function TestFormComponentExtended_div_63_div_2_div_1_div_20_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
460
|
+
i0.ɵɵelementStart(0, "span", 132);
|
|
460
461
|
i0.ɵɵtext(1);
|
|
461
462
|
i0.ɵɵelementEnd();
|
|
462
463
|
} if (rf & 2) {
|
|
@@ -465,9 +466,9 @@ function TestFormComponentExtended_div_51_div_2_div_1_div_20_span_2_Template(rf,
|
|
|
465
466
|
i0.ɵɵadvance();
|
|
466
467
|
i0.ɵɵtextInterpolate1("+", ctx_r0.getRunTags(run_r5).length - 3, "");
|
|
467
468
|
} }
|
|
468
|
-
function
|
|
469
|
-
i0.ɵɵelementStart(0, "div",
|
|
470
|
-
i0.ɵɵtemplate(1,
|
|
469
|
+
function TestFormComponentExtended_div_63_div_2_div_1_div_20_Template(rf, ctx) { if (rf & 1) {
|
|
470
|
+
i0.ɵɵelementStart(0, "div", 128);
|
|
471
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_63_div_2_div_1_div_20_span_1_Template, 2, 1, "span", 129)(2, TestFormComponentExtended_div_63_div_2_div_1_div_20_span_2_Template, 2, 1, "span", 130);
|
|
471
472
|
i0.ɵɵelementEnd();
|
|
472
473
|
} if (rf & 2) {
|
|
473
474
|
const run_r5 = i0.ɵɵnextContext().$implicit;
|
|
@@ -477,31 +478,31 @@ function TestFormComponentExtended_div_51_div_2_div_1_div_20_Template(rf, ctx) {
|
|
|
477
478
|
i0.ɵɵadvance();
|
|
478
479
|
i0.ɵɵproperty("ngIf", ctx_r0.getRunTags(run_r5).length > 3);
|
|
479
480
|
} }
|
|
480
|
-
function
|
|
481
|
+
function TestFormComponentExtended_div_63_div_2_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
481
482
|
const _r4 = i0.ɵɵgetCurrentView();
|
|
482
|
-
i0.ɵɵelementStart(0, "div",
|
|
483
|
-
i0.ɵɵlistener("click", function
|
|
484
|
-
i0.ɵɵelementStart(1, "div",
|
|
485
|
-
i0.ɵɵelement(2, "i",
|
|
483
|
+
i0.ɵɵelementStart(0, "div", 98);
|
|
484
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_63_div_2_div_1_Template_div_click_0_listener() { const run_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestRun(run_r5.ID)); });
|
|
485
|
+
i0.ɵɵelementStart(1, "div", 99);
|
|
486
|
+
i0.ɵɵelement(2, "i", 100);
|
|
486
487
|
i0.ɵɵelementEnd();
|
|
487
|
-
i0.ɵɵelementStart(3, "div",
|
|
488
|
+
i0.ɵɵelementStart(3, "div", 101)(4, "div", 102)(5, "span", 103);
|
|
488
489
|
i0.ɵɵtext(6);
|
|
489
490
|
i0.ɵɵelementEnd();
|
|
490
|
-
i0.ɵɵelementStart(7, "span",
|
|
491
|
+
i0.ɵɵelementStart(7, "span", 104);
|
|
491
492
|
i0.ɵɵtext(8);
|
|
492
493
|
i0.ɵɵelementEnd()();
|
|
493
|
-
i0.ɵɵelementStart(9, "div",
|
|
494
|
-
i0.ɵɵelement(11, "i",
|
|
494
|
+
i0.ɵɵelementStart(9, "div", 105)(10, "span");
|
|
495
|
+
i0.ɵɵelement(11, "i", 106);
|
|
495
496
|
i0.ɵɵtext(12);
|
|
496
497
|
i0.ɵɵelementEnd();
|
|
497
|
-
i0.ɵɵtemplate(13,
|
|
498
|
+
i0.ɵɵtemplate(13, TestFormComponentExtended_div_63_div_2_div_1_span_13_Template, 3, 1, "span", 107)(14, TestFormComponentExtended_div_63_div_2_div_1_span_14_Template, 3, 1, "span", 107)(15, TestFormComponentExtended_div_63_div_2_div_1_mj_entity_link_pill_15_Template, 1, 2, "mj-entity-link-pill", 108);
|
|
498
499
|
i0.ɵɵelementEnd();
|
|
499
|
-
i0.ɵɵelementStart(16, "div",
|
|
500
|
-
i0.ɵɵtemplate(17,
|
|
500
|
+
i0.ɵɵelementStart(16, "div", 109);
|
|
501
|
+
i0.ɵɵtemplate(17, TestFormComponentExtended_div_63_div_2_div_1_span_17_Template, 4, 17, "span", 110)(18, TestFormComponentExtended_div_63_div_2_div_1_ng_container_18_Template, 3, 2, "ng-container", 107)(19, TestFormComponentExtended_div_63_div_2_div_1_ng_container_19_Template, 3, 2, "ng-container", 107);
|
|
501
502
|
i0.ɵɵelementEnd();
|
|
502
|
-
i0.ɵɵtemplate(20,
|
|
503
|
+
i0.ɵɵtemplate(20, TestFormComponentExtended_div_63_div_2_div_1_div_20_Template, 3, 2, "div", 111);
|
|
503
504
|
i0.ɵɵelementEnd();
|
|
504
|
-
i0.ɵɵelement(21, "i",
|
|
505
|
+
i0.ɵɵelement(21, "i", 112);
|
|
505
506
|
i0.ɵɵelementEnd();
|
|
506
507
|
} if (rf & 2) {
|
|
507
508
|
const run_r5 = ctx.$implicit;
|
|
@@ -533,19 +534,19 @@ function TestFormComponentExtended_div_51_div_2_div_1_Template(rf, ctx) { if (rf
|
|
|
533
534
|
i0.ɵɵadvance();
|
|
534
535
|
i0.ɵɵproperty("ngIf", ctx_r0.getRunTags(run_r5).length > 0);
|
|
535
536
|
} }
|
|
536
|
-
function
|
|
537
|
-
i0.ɵɵelementStart(0, "div",
|
|
538
|
-
i0.ɵɵtemplate(1,
|
|
537
|
+
function TestFormComponentExtended_div_63_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
538
|
+
i0.ɵɵelementStart(0, "div", 96);
|
|
539
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_63_div_2_div_1_Template, 22, 26, "div", 97);
|
|
539
540
|
i0.ɵɵelementEnd();
|
|
540
541
|
} if (rf & 2) {
|
|
541
542
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
542
543
|
i0.ɵɵadvance();
|
|
543
544
|
i0.ɵɵproperty("ngForOf", ctx_r0.testRuns);
|
|
544
545
|
} }
|
|
545
|
-
function
|
|
546
|
+
function TestFormComponentExtended_div_63_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
546
547
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
547
|
-
i0.ɵɵelementStart(0, "div",
|
|
548
|
-
i0.ɵɵelement(2, "i",
|
|
548
|
+
i0.ɵɵelementStart(0, "div", 133)(1, "div", 134);
|
|
549
|
+
i0.ɵɵelement(2, "i", 135);
|
|
549
550
|
i0.ɵɵelementEnd();
|
|
550
551
|
i0.ɵɵelementStart(3, "h4");
|
|
551
552
|
i0.ɵɵtext(4, "No Test Runs Yet");
|
|
@@ -553,15 +554,15 @@ function TestFormComponentExtended_div_51_div_3_Template(rf, ctx) { if (rf & 1)
|
|
|
553
554
|
i0.ɵɵelementStart(5, "p");
|
|
554
555
|
i0.ɵɵtext(6, "Run this test to see execution history and results here.");
|
|
555
556
|
i0.ɵɵelementEnd();
|
|
556
|
-
i0.ɵɵelementStart(7, "button",
|
|
557
|
-
i0.ɵɵlistener("click", function
|
|
558
|
-
i0.ɵɵelement(8, "i",
|
|
557
|
+
i0.ɵɵelementStart(7, "button", 18);
|
|
558
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_63_div_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runTest()); });
|
|
559
|
+
i0.ɵɵelement(8, "i", 19);
|
|
559
560
|
i0.ɵɵtext(9, " Run Test Now ");
|
|
560
561
|
i0.ɵɵelementEnd()();
|
|
561
562
|
} }
|
|
562
|
-
function
|
|
563
|
-
i0.ɵɵelementStart(0, "div",
|
|
564
|
-
i0.ɵɵtemplate(1,
|
|
563
|
+
function TestFormComponentExtended_div_63_Template(rf, ctx) { if (rf & 1) {
|
|
564
|
+
i0.ɵɵelementStart(0, "div", 84);
|
|
565
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_63_div_1_Template, 3, 2, "div", 85)(2, TestFormComponentExtended_div_63_div_2_Template, 2, 1, "div", 86)(3, TestFormComponentExtended_div_63_div_3_Template, 10, 0, "div", 87);
|
|
565
566
|
i0.ɵɵelementEnd();
|
|
566
567
|
} if (rf & 2) {
|
|
567
568
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -572,24 +573,24 @@ function TestFormComponentExtended_div_51_Template(rf, ctx) { if (rf & 1) {
|
|
|
572
573
|
i0.ɵɵadvance();
|
|
573
574
|
i0.ɵɵproperty("ngIf", ctx_r0.testRunsLoaded && !ctx_r0.loadingRuns && ctx_r0.testRuns.length === 0);
|
|
574
575
|
} }
|
|
575
|
-
function
|
|
576
|
-
i0.ɵɵelementStart(0, "div",
|
|
577
|
-
i0.ɵɵelement(1, "div",
|
|
578
|
-
i0.ɵɵelementStart(2, "div",
|
|
579
|
-
i0.ɵɵelement(3, "div",
|
|
576
|
+
function TestFormComponentExtended_div_64_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
577
|
+
i0.ɵɵelementStart(0, "div", 91);
|
|
578
|
+
i0.ɵɵelement(1, "div", 92);
|
|
579
|
+
i0.ɵɵelementStart(2, "div", 93);
|
|
580
|
+
i0.ɵɵelement(3, "div", 94)(4, "div", 95);
|
|
580
581
|
i0.ɵɵelementEnd()();
|
|
581
582
|
} }
|
|
582
|
-
function
|
|
583
|
-
i0.ɵɵelementStart(0, "div",
|
|
584
|
-
i0.ɵɵtemplate(2,
|
|
583
|
+
function TestFormComponentExtended_div_64_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
584
|
+
i0.ɵɵelementStart(0, "div", 88)(1, "div", 89);
|
|
585
|
+
i0.ɵɵtemplate(2, TestFormComponentExtended_div_64_div_1_div_2_Template, 5, 0, "div", 90);
|
|
585
586
|
i0.ɵɵelementEnd()();
|
|
586
587
|
} if (rf & 2) {
|
|
587
588
|
i0.ɵɵadvance(2);
|
|
588
589
|
i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c1));
|
|
589
590
|
} }
|
|
590
|
-
function
|
|
591
|
+
function TestFormComponentExtended_div_64_div_2_div_1_span_10_Template(rf, ctx) { if (rf & 1) {
|
|
591
592
|
i0.ɵɵelementStart(0, "span");
|
|
592
|
-
i0.ɵɵelement(1, "i",
|
|
593
|
+
i0.ɵɵelement(1, "i", 53);
|
|
593
594
|
i0.ɵɵtext(2);
|
|
594
595
|
i0.ɵɵelementEnd();
|
|
595
596
|
} if (rf & 2) {
|
|
@@ -597,23 +598,23 @@ function TestFormComponentExtended_div_52_div_2_div_1_span_10_Template(rf, ctx)
|
|
|
597
598
|
i0.ɵɵadvance(2);
|
|
598
599
|
i0.ɵɵtextInterpolate1(" ", suiteTest_r10.Status, "");
|
|
599
600
|
} }
|
|
600
|
-
function
|
|
601
|
+
function TestFormComponentExtended_div_64_div_2_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
601
602
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
602
|
-
i0.ɵɵelementStart(0, "div",
|
|
603
|
-
i0.ɵɵlistener("click", function
|
|
604
|
-
i0.ɵɵelementStart(1, "div",
|
|
605
|
-
i0.ɵɵelement(2, "i",
|
|
603
|
+
i0.ɵɵelementStart(0, "div", 140);
|
|
604
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_64_div_2_div_1_Template_div_click_0_listener() { const suiteTest_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTestSuite(suiteTest_r10.SuiteID)); });
|
|
605
|
+
i0.ɵɵelementStart(1, "div", 141);
|
|
606
|
+
i0.ɵɵelement(2, "i", 30);
|
|
606
607
|
i0.ɵɵelementEnd();
|
|
607
|
-
i0.ɵɵelementStart(3, "div",
|
|
608
|
+
i0.ɵɵelementStart(3, "div", 142)(4, "div", 143);
|
|
608
609
|
i0.ɵɵtext(5);
|
|
609
610
|
i0.ɵɵelementEnd();
|
|
610
|
-
i0.ɵɵelementStart(6, "div",
|
|
611
|
-
i0.ɵɵelement(8, "i",
|
|
611
|
+
i0.ɵɵelementStart(6, "div", 144)(7, "span");
|
|
612
|
+
i0.ɵɵelement(8, "i", 145);
|
|
612
613
|
i0.ɵɵtext(9);
|
|
613
614
|
i0.ɵɵelementEnd();
|
|
614
|
-
i0.ɵɵtemplate(10,
|
|
615
|
+
i0.ɵɵtemplate(10, TestFormComponentExtended_div_64_div_2_div_1_span_10_Template, 3, 1, "span", 107);
|
|
615
616
|
i0.ɵɵelementEnd()();
|
|
616
|
-
i0.ɵɵelement(11, "i",
|
|
617
|
+
i0.ɵɵelement(11, "i", 112);
|
|
617
618
|
i0.ɵɵelementEnd();
|
|
618
619
|
} if (rf & 2) {
|
|
619
620
|
const suiteTest_r10 = ctx.$implicit;
|
|
@@ -624,18 +625,18 @@ function TestFormComponentExtended_div_52_div_2_div_1_Template(rf, ctx) { if (rf
|
|
|
624
625
|
i0.ɵɵadvance();
|
|
625
626
|
i0.ɵɵproperty("ngIf", suiteTest_r10.Status);
|
|
626
627
|
} }
|
|
627
|
-
function
|
|
628
|
-
i0.ɵɵelementStart(0, "div",
|
|
629
|
-
i0.ɵɵtemplate(1,
|
|
628
|
+
function TestFormComponentExtended_div_64_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
629
|
+
i0.ɵɵelementStart(0, "div", 138);
|
|
630
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_64_div_2_div_1_Template, 12, 3, "div", 139);
|
|
630
631
|
i0.ɵɵelementEnd();
|
|
631
632
|
} if (rf & 2) {
|
|
632
633
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
633
634
|
i0.ɵɵadvance();
|
|
634
635
|
i0.ɵɵproperty("ngForOf", ctx_r0.suiteTests);
|
|
635
636
|
} }
|
|
636
|
-
function
|
|
637
|
-
i0.ɵɵelementStart(0, "div",
|
|
638
|
-
i0.ɵɵelement(2, "i",
|
|
637
|
+
function TestFormComponentExtended_div_64_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
638
|
+
i0.ɵɵelementStart(0, "div", 133)(1, "div", 134);
|
|
639
|
+
i0.ɵɵelement(2, "i", 146);
|
|
639
640
|
i0.ɵɵelementEnd();
|
|
640
641
|
i0.ɵɵelementStart(3, "h4");
|
|
641
642
|
i0.ɵɵtext(4, "Not Part of Any Suite");
|
|
@@ -644,9 +645,9 @@ function TestFormComponentExtended_div_52_div_3_Template(rf, ctx) { if (rf & 1)
|
|
|
644
645
|
i0.ɵɵtext(6, "This test is not included in any test suites. Add it to a suite to run it with other tests.");
|
|
645
646
|
i0.ɵɵelementEnd()();
|
|
646
647
|
} }
|
|
647
|
-
function
|
|
648
|
-
i0.ɵɵelementStart(0, "div",
|
|
649
|
-
i0.ɵɵtemplate(1,
|
|
648
|
+
function TestFormComponentExtended_div_64_Template(rf, ctx) { if (rf & 1) {
|
|
649
|
+
i0.ɵɵelementStart(0, "div", 136);
|
|
650
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_64_div_1_Template, 3, 2, "div", 85)(2, TestFormComponentExtended_div_64_div_2_Template, 2, 1, "div", 137)(3, TestFormComponentExtended_div_64_div_3_Template, 7, 0, "div", 87);
|
|
650
651
|
i0.ɵɵelementEnd();
|
|
651
652
|
} if (rf & 2) {
|
|
652
653
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -657,20 +658,20 @@ function TestFormComponentExtended_div_52_Template(rf, ctx) { if (rf & 1) {
|
|
|
657
658
|
i0.ɵɵadvance();
|
|
658
659
|
i0.ɵɵproperty("ngIf", ctx_r0.suiteTestsLoaded && !ctx_r0.loadingSuites && ctx_r0.suiteTests.length === 0);
|
|
659
660
|
} }
|
|
660
|
-
function
|
|
661
|
-
i0.ɵɵelementStart(0, "div",
|
|
662
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
661
|
+
function TestFormComponentExtended_div_65_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
662
|
+
i0.ɵɵelementStart(0, "div", 88);
|
|
663
|
+
i0.ɵɵelement(1, "mj-loading", 149);
|
|
663
664
|
i0.ɵɵelementEnd();
|
|
664
665
|
} }
|
|
665
|
-
function
|
|
666
|
-
i0.ɵɵelementStart(0, "div",
|
|
667
|
-
i0.ɵɵelement(2, "i",
|
|
666
|
+
function TestFormComponentExtended_div_65_div_2_div_17_div_9_Template(rf, ctx) { if (rf & 1) {
|
|
667
|
+
i0.ɵɵelementStart(0, "div", 160)(1, "div", 166);
|
|
668
|
+
i0.ɵɵelement(2, "i", 167);
|
|
668
669
|
i0.ɵɵelementEnd();
|
|
669
|
-
i0.ɵɵelementStart(3, "div",
|
|
670
|
+
i0.ɵɵelementStart(3, "div", 162)(4, "div", 163);
|
|
670
671
|
i0.ɵɵtext(5);
|
|
671
|
-
i0.ɵɵelement(6, "i",
|
|
672
|
+
i0.ɵɵelement(6, "i", 168);
|
|
672
673
|
i0.ɵɵelementEnd();
|
|
673
|
-
i0.ɵɵelementStart(7, "div",
|
|
674
|
+
i0.ɵɵelementStart(7, "div", 164);
|
|
674
675
|
i0.ɵɵtext(8, "Pass Rate");
|
|
675
676
|
i0.ɵɵelementEnd()()();
|
|
676
677
|
} if (rf & 2) {
|
|
@@ -680,14 +681,14 @@ function TestFormComponentExtended_div_53_div_2_div_17_div_9_Template(rf, ctx) {
|
|
|
680
681
|
i0.ɵɵadvance();
|
|
681
682
|
i0.ɵɵclassProp("fa-arrow-up", ctx_r0.getPassRateTrend() === "up")("fa-arrow-down", ctx_r0.getPassRateTrend() === "down")("fa-minus", ctx_r0.getPassRateTrend() === "stable")("trend-up", ctx_r0.getPassRateTrend() === "up")("trend-down", ctx_r0.getPassRateTrend() === "down");
|
|
682
683
|
} }
|
|
683
|
-
function
|
|
684
|
-
i0.ɵɵelementStart(0, "div",
|
|
685
|
-
i0.ɵɵelement(2, "i",
|
|
684
|
+
function TestFormComponentExtended_div_65_div_2_div_17_div_10_Template(rf, ctx) { if (rf & 1) {
|
|
685
|
+
i0.ɵɵelementStart(0, "div", 160)(1, "div", 161);
|
|
686
|
+
i0.ɵɵelement(2, "i", 169);
|
|
686
687
|
i0.ɵɵelementEnd();
|
|
687
|
-
i0.ɵɵelementStart(3, "div",
|
|
688
|
+
i0.ɵɵelementStart(3, "div", 162)(4, "div", 163);
|
|
688
689
|
i0.ɵɵtext(5);
|
|
689
690
|
i0.ɵɵelementEnd();
|
|
690
|
-
i0.ɵɵelementStart(6, "div",
|
|
691
|
+
i0.ɵɵelementStart(6, "div", 164);
|
|
691
692
|
i0.ɵɵtext(7, "Avg Score");
|
|
692
693
|
i0.ɵɵelementEnd()()();
|
|
693
694
|
} if (rf & 2) {
|
|
@@ -695,33 +696,33 @@ function TestFormComponentExtended_div_53_div_2_div_17_div_10_Template(rf, ctx)
|
|
|
695
696
|
i0.ɵɵadvance(5);
|
|
696
697
|
i0.ɵɵtextInterpolate1("", (ctx_r0.getOverallAvgScore() * 100).toFixed(1), "%");
|
|
697
698
|
} }
|
|
698
|
-
function
|
|
699
|
-
i0.ɵɵelementStart(0, "div",
|
|
700
|
-
i0.ɵɵelement(3, "i",
|
|
699
|
+
function TestFormComponentExtended_div_65_div_2_div_17_Template(rf, ctx) { if (rf & 1) {
|
|
700
|
+
i0.ɵɵelementStart(0, "div", 159)(1, "div", 160)(2, "div", 161);
|
|
701
|
+
i0.ɵɵelement(3, "i", 135);
|
|
701
702
|
i0.ɵɵelementEnd();
|
|
702
|
-
i0.ɵɵelementStart(4, "div",
|
|
703
|
+
i0.ɵɵelementStart(4, "div", 162)(5, "div", 163);
|
|
703
704
|
i0.ɵɵtext(6);
|
|
704
705
|
i0.ɵɵelementEnd();
|
|
705
|
-
i0.ɵɵelementStart(7, "div",
|
|
706
|
+
i0.ɵɵelementStart(7, "div", 164);
|
|
706
707
|
i0.ɵɵtext(8, "Total Runs");
|
|
707
708
|
i0.ɵɵelementEnd()()();
|
|
708
|
-
i0.ɵɵtemplate(9,
|
|
709
|
-
i0.ɵɵelementStart(11, "div",
|
|
710
|
-
i0.ɵɵelement(13, "i",
|
|
709
|
+
i0.ɵɵtemplate(9, TestFormComponentExtended_div_65_div_2_div_17_div_9_Template, 9, 11, "div", 165)(10, TestFormComponentExtended_div_65_div_2_div_17_div_10_Template, 8, 1, "div", 165);
|
|
710
|
+
i0.ɵɵelementStart(11, "div", 160)(12, "div", 161);
|
|
711
|
+
i0.ɵɵelement(13, "i", 113);
|
|
711
712
|
i0.ɵɵelementEnd();
|
|
712
|
-
i0.ɵɵelementStart(14, "div",
|
|
713
|
+
i0.ɵɵelementStart(14, "div", 162)(15, "div", 163);
|
|
713
714
|
i0.ɵɵtext(16);
|
|
714
715
|
i0.ɵɵelementEnd();
|
|
715
|
-
i0.ɵɵelementStart(17, "div",
|
|
716
|
+
i0.ɵɵelementStart(17, "div", 164);
|
|
716
717
|
i0.ɵɵtext(18, "Avg Duration");
|
|
717
718
|
i0.ɵɵelementEnd()()();
|
|
718
|
-
i0.ɵɵelementStart(19, "div",
|
|
719
|
-
i0.ɵɵelement(21, "i",
|
|
719
|
+
i0.ɵɵelementStart(19, "div", 160)(20, "div", 161);
|
|
720
|
+
i0.ɵɵelement(21, "i", 114);
|
|
720
721
|
i0.ɵɵelementEnd();
|
|
721
|
-
i0.ɵɵelementStart(22, "div",
|
|
722
|
+
i0.ɵɵelementStart(22, "div", 162)(23, "div", 163);
|
|
722
723
|
i0.ɵɵtext(24);
|
|
723
724
|
i0.ɵɵelementEnd();
|
|
724
|
-
i0.ɵɵelementStart(25, "div",
|
|
725
|
+
i0.ɵɵelementStart(25, "div", 164);
|
|
725
726
|
i0.ɵɵtext(26, "Avg Cost");
|
|
726
727
|
i0.ɵɵelementEnd()()()();
|
|
727
728
|
} if (rf & 2) {
|
|
@@ -737,28 +738,28 @@ function TestFormComponentExtended_div_53_div_2_div_17_Template(rf, ctx) { if (r
|
|
|
737
738
|
i0.ɵɵadvance(8);
|
|
738
739
|
i0.ɵɵtextInterpolate(ctx_r0.formatCost(ctx_r0.getOverallAvgCost()));
|
|
739
740
|
} }
|
|
740
|
-
function
|
|
741
|
+
function TestFormComponentExtended_div_65_div_2_div_18_th_12_Template(rf, ctx) { if (rf & 1) {
|
|
741
742
|
i0.ɵɵelementStart(0, "th");
|
|
742
743
|
i0.ɵɵtext(1, "Passed");
|
|
743
744
|
i0.ɵɵelementEnd();
|
|
744
745
|
} }
|
|
745
|
-
function
|
|
746
|
+
function TestFormComponentExtended_div_65_div_2_div_18_th_13_Template(rf, ctx) { if (rf & 1) {
|
|
746
747
|
i0.ɵɵelementStart(0, "th");
|
|
747
748
|
i0.ɵɵtext(1, "Failed");
|
|
748
749
|
i0.ɵɵelementEnd();
|
|
749
750
|
} }
|
|
750
|
-
function
|
|
751
|
+
function TestFormComponentExtended_div_65_div_2_div_18_th_14_Template(rf, ctx) { if (rf & 1) {
|
|
751
752
|
i0.ɵɵelementStart(0, "th");
|
|
752
753
|
i0.ɵɵtext(1, "Pass Rate");
|
|
753
754
|
i0.ɵɵelementEnd();
|
|
754
755
|
} }
|
|
755
|
-
function
|
|
756
|
+
function TestFormComponentExtended_div_65_div_2_div_18_th_15_Template(rf, ctx) { if (rf & 1) {
|
|
756
757
|
i0.ɵɵelementStart(0, "th");
|
|
757
758
|
i0.ɵɵtext(1, "Avg Score");
|
|
758
759
|
i0.ɵɵelementEnd();
|
|
759
760
|
} }
|
|
760
|
-
function
|
|
761
|
-
i0.ɵɵelementStart(0, "td",
|
|
761
|
+
function TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_6_Template(rf, ctx) { if (rf & 1) {
|
|
762
|
+
i0.ɵɵelementStart(0, "td", 183);
|
|
762
763
|
i0.ɵɵtext(1);
|
|
763
764
|
i0.ɵɵelementEnd();
|
|
764
765
|
} if (rf & 2) {
|
|
@@ -766,8 +767,8 @@ function TestFormComponentExtended_div_53_div_2_div_18_tr_21_td_6_Template(rf, c
|
|
|
766
767
|
i0.ɵɵadvance();
|
|
767
768
|
i0.ɵɵtextInterpolate(day_r12.passCount);
|
|
768
769
|
} }
|
|
769
|
-
function
|
|
770
|
-
i0.ɵɵelementStart(0, "td",
|
|
770
|
+
function TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_7_Template(rf, ctx) { if (rf & 1) {
|
|
771
|
+
i0.ɵɵelementStart(0, "td", 184);
|
|
771
772
|
i0.ɵɵtext(1);
|
|
772
773
|
i0.ɵɵelementEnd();
|
|
773
774
|
} if (rf & 2) {
|
|
@@ -775,10 +776,10 @@ function TestFormComponentExtended_div_53_div_2_div_18_tr_21_td_7_Template(rf, c
|
|
|
775
776
|
i0.ɵɵadvance();
|
|
776
777
|
i0.ɵɵtextInterpolate(day_r12.failCount);
|
|
777
778
|
} }
|
|
778
|
-
function
|
|
779
|
-
i0.ɵɵelementStart(0, "td",
|
|
780
|
-
i0.ɵɵelement(2, "div",
|
|
781
|
-
i0.ɵɵelementStart(3, "span",
|
|
779
|
+
function TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_8_Template(rf, ctx) { if (rf & 1) {
|
|
780
|
+
i0.ɵɵelementStart(0, "td", 185)(1, "div", 186);
|
|
781
|
+
i0.ɵɵelement(2, "div", 187);
|
|
782
|
+
i0.ɵɵelementStart(3, "span", 188);
|
|
782
783
|
i0.ɵɵtext(4);
|
|
783
784
|
i0.ɵɵelementEnd()()();
|
|
784
785
|
} if (rf & 2) {
|
|
@@ -788,8 +789,8 @@ function TestFormComponentExtended_div_53_div_2_div_18_tr_21_td_8_Template(rf, c
|
|
|
788
789
|
i0.ɵɵadvance(2);
|
|
789
790
|
i0.ɵɵtextInterpolate1("", day_r12.passRate.toFixed(1), "%");
|
|
790
791
|
} }
|
|
791
|
-
function
|
|
792
|
-
i0.ɵɵelementStart(0, "td",
|
|
792
|
+
function TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_9_Template(rf, ctx) { if (rf & 1) {
|
|
793
|
+
i0.ɵɵelementStart(0, "td", 189);
|
|
793
794
|
i0.ɵɵtext(1);
|
|
794
795
|
i0.ɵɵelementEnd();
|
|
795
796
|
} if (rf & 2) {
|
|
@@ -797,19 +798,19 @@ function TestFormComponentExtended_div_53_div_2_div_18_tr_21_td_9_Template(rf, c
|
|
|
797
798
|
i0.ɵɵadvance();
|
|
798
799
|
i0.ɵɵtextInterpolate1("", (day_r12.avgScore * 100).toFixed(1), "%");
|
|
799
800
|
} }
|
|
800
|
-
function
|
|
801
|
-
i0.ɵɵelementStart(0, "tr")(1, "td",
|
|
801
|
+
function TestFormComponentExtended_div_65_div_2_div_18_tr_21_Template(rf, ctx) { if (rf & 1) {
|
|
802
|
+
i0.ɵɵelementStart(0, "tr")(1, "td", 175);
|
|
802
803
|
i0.ɵɵtext(2);
|
|
803
804
|
i0.ɵɵpipe(3, "date");
|
|
804
805
|
i0.ɵɵelementEnd();
|
|
805
|
-
i0.ɵɵelementStart(4, "td",
|
|
806
|
+
i0.ɵɵelementStart(4, "td", 176);
|
|
806
807
|
i0.ɵɵtext(5);
|
|
807
808
|
i0.ɵɵelementEnd();
|
|
808
|
-
i0.ɵɵtemplate(6,
|
|
809
|
-
i0.ɵɵelementStart(10, "td",
|
|
809
|
+
i0.ɵɵtemplate(6, TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_6_Template, 2, 1, "td", 177)(7, TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_7_Template, 2, 1, "td", 178)(8, TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_8_Template, 5, 3, "td", 179)(9, TestFormComponentExtended_div_65_div_2_div_18_tr_21_td_9_Template, 2, 1, "td", 180);
|
|
810
|
+
i0.ɵɵelementStart(10, "td", 181);
|
|
810
811
|
i0.ɵɵtext(11);
|
|
811
812
|
i0.ɵɵelementEnd();
|
|
812
|
-
i0.ɵɵelementStart(12, "td",
|
|
813
|
+
i0.ɵɵelementStart(12, "td", 182);
|
|
813
814
|
i0.ɵɵtext(13);
|
|
814
815
|
i0.ɵɵelementEnd()();
|
|
815
816
|
} if (rf & 2) {
|
|
@@ -832,18 +833,18 @@ function TestFormComponentExtended_div_53_div_2_div_18_tr_21_Template(rf, ctx) {
|
|
|
832
833
|
i0.ɵɵadvance(2);
|
|
833
834
|
i0.ɵɵtextInterpolate(ctx_r0.formatCost(day_r12.avgCost));
|
|
834
835
|
} }
|
|
835
|
-
function
|
|
836
|
-
i0.ɵɵelementStart(0, "div",
|
|
837
|
-
i0.ɵɵelement(2, "i",
|
|
836
|
+
function TestFormComponentExtended_div_65_div_2_div_18_Template(rf, ctx) { if (rf & 1) {
|
|
837
|
+
i0.ɵɵelementStart(0, "div", 170)(1, "h3");
|
|
838
|
+
i0.ɵɵelement(2, "i", 171);
|
|
838
839
|
i0.ɵɵtext(3, " Daily Performance");
|
|
839
840
|
i0.ɵɵelementEnd();
|
|
840
|
-
i0.ɵɵelementStart(4, "div",
|
|
841
|
+
i0.ɵɵelementStart(4, "div", 172)(5, "table", 173)(6, "thead")(7, "tr")(8, "th");
|
|
841
842
|
i0.ɵɵtext(9, "Date");
|
|
842
843
|
i0.ɵɵelementEnd();
|
|
843
844
|
i0.ɵɵelementStart(10, "th");
|
|
844
845
|
i0.ɵɵtext(11, "Runs");
|
|
845
846
|
i0.ɵɵelementEnd();
|
|
846
|
-
i0.ɵɵtemplate(12,
|
|
847
|
+
i0.ɵɵtemplate(12, TestFormComponentExtended_div_65_div_2_div_18_th_12_Template, 2, 0, "th", 107)(13, TestFormComponentExtended_div_65_div_2_div_18_th_13_Template, 2, 0, "th", 107)(14, TestFormComponentExtended_div_65_div_2_div_18_th_14_Template, 2, 0, "th", 107)(15, TestFormComponentExtended_div_65_div_2_div_18_th_15_Template, 2, 0, "th", 107);
|
|
847
848
|
i0.ɵɵelementStart(16, "th");
|
|
848
849
|
i0.ɵɵtext(17, "Avg Duration");
|
|
849
850
|
i0.ɵɵelementEnd();
|
|
@@ -851,7 +852,7 @@ function TestFormComponentExtended_div_53_div_2_div_18_Template(rf, ctx) { if (r
|
|
|
851
852
|
i0.ɵɵtext(19, "Avg Cost");
|
|
852
853
|
i0.ɵɵelementEnd()()();
|
|
853
854
|
i0.ɵɵelementStart(20, "tbody");
|
|
854
|
-
i0.ɵɵtemplate(21,
|
|
855
|
+
i0.ɵɵtemplate(21, TestFormComponentExtended_div_65_div_2_div_18_tr_21_Template, 14, 11, "tr", 174);
|
|
855
856
|
i0.ɵɵelementEnd()()()();
|
|
856
857
|
} if (rf & 2) {
|
|
857
858
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -866,8 +867,8 @@ function TestFormComponentExtended_div_53_div_2_div_18_Template(rf, ctx) { if (r
|
|
|
866
867
|
i0.ɵɵadvance(6);
|
|
867
868
|
i0.ɵɵproperty("ngForOf", ctx_r0.historyData);
|
|
868
869
|
} }
|
|
869
|
-
function
|
|
870
|
-
i0.ɵɵelementStart(0, "span",
|
|
870
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_div_4_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
871
|
+
i0.ɵɵelementStart(0, "span", 205);
|
|
871
872
|
i0.ɵɵtext(1);
|
|
872
873
|
i0.ɵɵelementEnd();
|
|
873
874
|
} if (rf & 2) {
|
|
@@ -875,8 +876,8 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_div_4_span_1_Templa
|
|
|
875
876
|
i0.ɵɵadvance();
|
|
876
877
|
i0.ɵɵtextInterpolate(tag_r15);
|
|
877
878
|
} }
|
|
878
|
-
function
|
|
879
|
-
i0.ɵɵelementStart(0, "span",
|
|
879
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_div_4_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
880
|
+
i0.ɵɵelementStart(0, "span", 206);
|
|
880
881
|
i0.ɵɵtext(1);
|
|
881
882
|
i0.ɵɵelementEnd();
|
|
882
883
|
} if (rf & 2) {
|
|
@@ -884,9 +885,9 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_div_4_span_2_Templa
|
|
|
884
885
|
i0.ɵɵadvance();
|
|
885
886
|
i0.ɵɵtextInterpolate1("+", suite_r14.tags.length - 3, "");
|
|
886
887
|
} }
|
|
887
|
-
function
|
|
888
|
-
i0.ɵɵelementStart(0, "div",
|
|
889
|
-
i0.ɵɵtemplate(1,
|
|
888
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_div_4_Template(rf, ctx) { if (rf & 1) {
|
|
889
|
+
i0.ɵɵelementStart(0, "div", 202);
|
|
890
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_65_div_2_div_19_div_5_div_4_span_1_Template, 2, 1, "span", 203)(2, TestFormComponentExtended_div_65_div_2_div_19_div_5_div_4_span_2_Template, 2, 1, "span", 204);
|
|
890
891
|
i0.ɵɵelementEnd();
|
|
891
892
|
} if (rf & 2) {
|
|
892
893
|
const suite_r14 = i0.ɵɵnextContext().$implicit;
|
|
@@ -895,11 +896,11 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_div_4_Template(rf,
|
|
|
895
896
|
i0.ɵɵadvance();
|
|
896
897
|
i0.ɵɵproperty("ngIf", suite_r14.tags.length > 3);
|
|
897
898
|
} }
|
|
898
|
-
function
|
|
899
|
-
i0.ɵɵelementStart(0, "div",
|
|
899
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_div_11_Template(rf, ctx) { if (rf & 1) {
|
|
900
|
+
i0.ɵɵelementStart(0, "div", 197)(1, "span", 207);
|
|
900
901
|
i0.ɵɵtext(2);
|
|
901
902
|
i0.ɵɵelementEnd();
|
|
902
|
-
i0.ɵɵelementStart(3, "span",
|
|
903
|
+
i0.ɵɵelementStart(3, "span", 199);
|
|
903
904
|
i0.ɵɵtext(4, "Pass Rate");
|
|
904
905
|
i0.ɵɵelementEnd()();
|
|
905
906
|
} if (rf & 2) {
|
|
@@ -909,11 +910,11 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_div_11_Template(rf,
|
|
|
909
910
|
i0.ɵɵadvance();
|
|
910
911
|
i0.ɵɵtextInterpolate1(" ", suite_r14.passRate.toFixed(1), "% ");
|
|
911
912
|
} }
|
|
912
|
-
function
|
|
913
|
-
i0.ɵɵelementStart(0, "div",
|
|
913
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_div_12_Template(rf, ctx) { if (rf & 1) {
|
|
914
|
+
i0.ɵɵelementStart(0, "div", 197)(1, "span", 198);
|
|
914
915
|
i0.ɵɵtext(2);
|
|
915
916
|
i0.ɵɵelementEnd();
|
|
916
|
-
i0.ɵɵelementStart(3, "span",
|
|
917
|
+
i0.ɵɵelementStart(3, "span", 199);
|
|
917
918
|
i0.ɵɵtext(4, "Avg Score");
|
|
918
919
|
i0.ɵɵelementEnd()();
|
|
919
920
|
} if (rf & 2) {
|
|
@@ -921,11 +922,11 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_div_12_Template(rf,
|
|
|
921
922
|
i0.ɵɵadvance(2);
|
|
922
923
|
i0.ɵɵtextInterpolate1("", (suite_r14.avgScore * 100).toFixed(1), "%");
|
|
923
924
|
} }
|
|
924
|
-
function
|
|
925
|
-
i0.ɵɵelementStart(0, "div",
|
|
925
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_div_23_Template(rf, ctx) { if (rf & 1) {
|
|
926
|
+
i0.ɵɵelementStart(0, "div", 197)(1, "span", 198);
|
|
926
927
|
i0.ɵɵtext(2);
|
|
927
928
|
i0.ɵɵelementEnd();
|
|
928
|
-
i0.ɵɵelementStart(3, "span",
|
|
929
|
+
i0.ɵɵelementStart(3, "span", 199);
|
|
929
930
|
i0.ɵɵtext(4, "Last Run");
|
|
930
931
|
i0.ɵɵelementEnd()();
|
|
931
932
|
} if (rf & 2) {
|
|
@@ -934,37 +935,37 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_div_23_Template(rf,
|
|
|
934
935
|
i0.ɵɵadvance(2);
|
|
935
936
|
i0.ɵɵtextInterpolate(ctx_r0.getRelativeTime(suite_r14.lastRun));
|
|
936
937
|
} }
|
|
937
|
-
function
|
|
938
|
+
function TestFormComponentExtended_div_65_div_2_div_19_div_5_Template(rf, ctx) { if (rf & 1) {
|
|
938
939
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
939
|
-
i0.ɵɵelementStart(0, "div",
|
|
940
|
-
i0.ɵɵlistener("click", function
|
|
941
|
-
i0.ɵɵelementStart(1, "div",
|
|
940
|
+
i0.ɵɵelementStart(0, "div", 192);
|
|
941
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_div_19_div_5_Template_div_click_0_listener() { const suite_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteFromHistory(suite_r14.suiteId)); });
|
|
942
|
+
i0.ɵɵelementStart(1, "div", 193)(2, "div", 194);
|
|
942
943
|
i0.ɵɵtext(3);
|
|
943
944
|
i0.ɵɵelementEnd();
|
|
944
|
-
i0.ɵɵtemplate(4,
|
|
945
|
+
i0.ɵɵtemplate(4, TestFormComponentExtended_div_65_div_2_div_19_div_5_div_4_Template, 3, 2, "div", 195);
|
|
945
946
|
i0.ɵɵelementEnd();
|
|
946
|
-
i0.ɵɵelementStart(5, "div",
|
|
947
|
+
i0.ɵɵelementStart(5, "div", 196)(6, "div", 197)(7, "span", 198);
|
|
947
948
|
i0.ɵɵtext(8);
|
|
948
949
|
i0.ɵɵelementEnd();
|
|
949
|
-
i0.ɵɵelementStart(9, "span",
|
|
950
|
+
i0.ɵɵelementStart(9, "span", 199);
|
|
950
951
|
i0.ɵɵtext(10, "Runs");
|
|
951
952
|
i0.ɵɵelementEnd()();
|
|
952
|
-
i0.ɵɵtemplate(11,
|
|
953
|
-
i0.ɵɵelementStart(13, "div",
|
|
953
|
+
i0.ɵɵtemplate(11, TestFormComponentExtended_div_65_div_2_div_19_div_5_div_11_Template, 5, 5, "div", 200)(12, TestFormComponentExtended_div_65_div_2_div_19_div_5_div_12_Template, 5, 1, "div", 200);
|
|
954
|
+
i0.ɵɵelementStart(13, "div", 197)(14, "span", 198);
|
|
954
955
|
i0.ɵɵtext(15);
|
|
955
956
|
i0.ɵɵelementEnd();
|
|
956
|
-
i0.ɵɵelementStart(16, "span",
|
|
957
|
+
i0.ɵɵelementStart(16, "span", 199);
|
|
957
958
|
i0.ɵɵtext(17, "Avg Duration");
|
|
958
959
|
i0.ɵɵelementEnd()();
|
|
959
|
-
i0.ɵɵelementStart(18, "div",
|
|
960
|
+
i0.ɵɵelementStart(18, "div", 197)(19, "span", 198);
|
|
960
961
|
i0.ɵɵtext(20);
|
|
961
962
|
i0.ɵɵelementEnd();
|
|
962
|
-
i0.ɵɵelementStart(21, "span",
|
|
963
|
+
i0.ɵɵelementStart(21, "span", 199);
|
|
963
964
|
i0.ɵɵtext(22, "Avg Cost");
|
|
964
965
|
i0.ɵɵelementEnd()();
|
|
965
|
-
i0.ɵɵtemplate(23,
|
|
966
|
+
i0.ɵɵtemplate(23, TestFormComponentExtended_div_65_div_2_div_19_div_5_div_23_Template, 5, 1, "div", 200);
|
|
966
967
|
i0.ɵɵelementEnd();
|
|
967
|
-
i0.ɵɵelement(24, "i",
|
|
968
|
+
i0.ɵɵelement(24, "i", 201);
|
|
968
969
|
i0.ɵɵelementEnd();
|
|
969
970
|
} if (rf & 2) {
|
|
970
971
|
const suite_r14 = ctx.$implicit;
|
|
@@ -986,23 +987,23 @@ function TestFormComponentExtended_div_53_div_2_div_19_div_5_Template(rf, ctx) {
|
|
|
986
987
|
i0.ɵɵadvance(3);
|
|
987
988
|
i0.ɵɵproperty("ngIf", suite_r14.lastRun);
|
|
988
989
|
} }
|
|
989
|
-
function
|
|
990
|
-
i0.ɵɵelementStart(0, "div",
|
|
991
|
-
i0.ɵɵelement(2, "i",
|
|
990
|
+
function TestFormComponentExtended_div_65_div_2_div_19_Template(rf, ctx) { if (rf & 1) {
|
|
991
|
+
i0.ɵɵelementStart(0, "div", 170)(1, "h3");
|
|
992
|
+
i0.ɵɵelement(2, "i", 30);
|
|
992
993
|
i0.ɵɵtext(3, " Performance by Suite");
|
|
993
994
|
i0.ɵɵelementEnd();
|
|
994
|
-
i0.ɵɵelementStart(4, "div",
|
|
995
|
-
i0.ɵɵtemplate(5,
|
|
995
|
+
i0.ɵɵelementStart(4, "div", 190);
|
|
996
|
+
i0.ɵɵtemplate(5, TestFormComponentExtended_div_65_div_2_div_19_div_5_Template, 25, 8, "div", 191);
|
|
996
997
|
i0.ɵɵelementEnd()();
|
|
997
998
|
} if (rf & 2) {
|
|
998
999
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
999
1000
|
i0.ɵɵadvance(5);
|
|
1000
1001
|
i0.ɵɵproperty("ngForOf", ctx_r0.suitePerformance);
|
|
1001
1002
|
} }
|
|
1002
|
-
function
|
|
1003
|
+
function TestFormComponentExtended_div_65_div_2_div_20_Template(rf, ctx) { if (rf & 1) {
|
|
1003
1004
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
1004
|
-
i0.ɵɵelementStart(0, "div",
|
|
1005
|
-
i0.ɵɵelement(2, "i",
|
|
1005
|
+
i0.ɵɵelementStart(0, "div", 133)(1, "div", 134);
|
|
1006
|
+
i0.ɵɵelement(2, "i", 31);
|
|
1006
1007
|
i0.ɵɵelementEnd();
|
|
1007
1008
|
i0.ɵɵelementStart(3, "h4");
|
|
1008
1009
|
i0.ɵɵtext(4, "No History Available");
|
|
@@ -1010,39 +1011,39 @@ function TestFormComponentExtended_div_53_div_2_div_20_Template(rf, ctx) { if (r
|
|
|
1010
1011
|
i0.ɵɵelementStart(5, "p");
|
|
1011
1012
|
i0.ɵɵtext(6, "Run this test to start building history and analytics data.");
|
|
1012
1013
|
i0.ɵɵelementEnd();
|
|
1013
|
-
i0.ɵɵelementStart(7, "button",
|
|
1014
|
-
i0.ɵɵlistener("click", function
|
|
1015
|
-
i0.ɵɵelement(8, "i",
|
|
1014
|
+
i0.ɵɵelementStart(7, "button", 18);
|
|
1015
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_div_20_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r16); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.runTest()); });
|
|
1016
|
+
i0.ɵɵelement(8, "i", 19);
|
|
1016
1017
|
i0.ɵɵtext(9, " Run Test Now ");
|
|
1017
1018
|
i0.ɵɵelementEnd()();
|
|
1018
1019
|
} }
|
|
1019
|
-
function
|
|
1020
|
+
function TestFormComponentExtended_div_65_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
1020
1021
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
1021
|
-
i0.ɵɵelementStart(0, "div",
|
|
1022
|
+
i0.ɵɵelementStart(0, "div", 150)(1, "div", 151)(2, "div", 152)(3, "span", 153);
|
|
1022
1023
|
i0.ɵɵtext(4, "Time Range:");
|
|
1023
1024
|
i0.ɵɵelementEnd();
|
|
1024
|
-
i0.ɵɵelementStart(5, "button",
|
|
1025
|
-
i0.ɵɵlistener("click", function
|
|
1025
|
+
i0.ɵɵelementStart(5, "button", 154);
|
|
1026
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("7d")); });
|
|
1026
1027
|
i0.ɵɵtext(6, "7 Days");
|
|
1027
1028
|
i0.ɵɵelementEnd();
|
|
1028
|
-
i0.ɵɵelementStart(7, "button",
|
|
1029
|
-
i0.ɵɵlistener("click", function
|
|
1029
|
+
i0.ɵɵelementStart(7, "button", 154);
|
|
1030
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("30d")); });
|
|
1030
1031
|
i0.ɵɵtext(8, "30 Days");
|
|
1031
1032
|
i0.ɵɵelementEnd();
|
|
1032
|
-
i0.ɵɵelementStart(9, "button",
|
|
1033
|
-
i0.ɵɵlistener("click", function
|
|
1033
|
+
i0.ɵɵelementStart(9, "button", 154);
|
|
1034
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("90d")); });
|
|
1034
1035
|
i0.ɵɵtext(10, "90 Days");
|
|
1035
1036
|
i0.ɵɵelementEnd();
|
|
1036
|
-
i0.ɵɵelementStart(11, "button",
|
|
1037
|
-
i0.ɵɵlistener("click", function
|
|
1037
|
+
i0.ɵɵelementStart(11, "button", 154);
|
|
1038
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setHistoryTimeRange("all")); });
|
|
1038
1039
|
i0.ɵɵtext(12, "All Time");
|
|
1039
1040
|
i0.ɵɵelementEnd()();
|
|
1040
|
-
i0.ɵɵelementStart(13, "div",
|
|
1041
|
-
i0.ɵɵlistener("click", function
|
|
1042
|
-
i0.ɵɵelement(15, "i",
|
|
1041
|
+
i0.ɵɵelementStart(13, "div", 155)(14, "button", 20);
|
|
1042
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_65_div_2_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.exportHistoryToCSV()); });
|
|
1043
|
+
i0.ɵɵelement(15, "i", 156);
|
|
1043
1044
|
i0.ɵɵtext(16, " Export CSV ");
|
|
1044
1045
|
i0.ɵɵelementEnd()()();
|
|
1045
|
-
i0.ɵɵtemplate(17,
|
|
1046
|
+
i0.ɵɵtemplate(17, TestFormComponentExtended_div_65_div_2_div_17_Template, 27, 5, "div", 157)(18, TestFormComponentExtended_div_65_div_2_div_18_Template, 22, 5, "div", 158)(19, TestFormComponentExtended_div_65_div_2_div_19_Template, 6, 1, "div", 158)(20, TestFormComponentExtended_div_65_div_2_div_20_Template, 10, 0, "div", 87);
|
|
1046
1047
|
i0.ɵɵelementEnd();
|
|
1047
1048
|
} if (rf & 2) {
|
|
1048
1049
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -1065,9 +1066,9 @@ function TestFormComponentExtended_div_53_div_2_Template(rf, ctx) { if (rf & 1)
|
|
|
1065
1066
|
i0.ɵɵadvance();
|
|
1066
1067
|
i0.ɵɵproperty("ngIf", ctx_r0.historyData.length === 0);
|
|
1067
1068
|
} }
|
|
1068
|
-
function
|
|
1069
|
-
i0.ɵɵelementStart(0, "div",
|
|
1070
|
-
i0.ɵɵtemplate(1,
|
|
1069
|
+
function TestFormComponentExtended_div_65_Template(rf, ctx) { if (rf & 1) {
|
|
1070
|
+
i0.ɵɵelementStart(0, "div", 147);
|
|
1071
|
+
i0.ɵɵtemplate(1, TestFormComponentExtended_div_65_div_1_Template, 2, 0, "div", 85)(2, TestFormComponentExtended_div_65_div_2_Template, 21, 13, "div", 148);
|
|
1071
1072
|
i0.ɵɵelementEnd();
|
|
1072
1073
|
} if (rf & 2) {
|
|
1073
1074
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -1076,37 +1077,37 @@ function TestFormComponentExtended_div_53_Template(rf, ctx) { if (rf & 1) {
|
|
|
1076
1077
|
i0.ɵɵadvance();
|
|
1077
1078
|
i0.ɵɵproperty("ngIf", !ctx_r0.loadingHistory && ctx_r0.historyLoaded);
|
|
1078
1079
|
} }
|
|
1079
|
-
function
|
|
1080
|
+
function TestFormComponentExtended_div_68_Template(rf, ctx) { if (rf & 1) {
|
|
1080
1081
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
1081
|
-
i0.ɵɵelementStart(0, "div",
|
|
1082
|
-
i0.ɵɵelement(2, "i",
|
|
1082
|
+
i0.ɵɵelementStart(0, "div", 208)(1, "div", 209);
|
|
1083
|
+
i0.ɵɵelement(2, "i", 39);
|
|
1083
1084
|
i0.ɵɵtext(3, " Shortcuts ");
|
|
1084
|
-
i0.ɵɵelementStart(4, "button",
|
|
1085
|
-
i0.ɵɵlistener("click", function
|
|
1086
|
-
i0.ɵɵelement(5, "i",
|
|
1085
|
+
i0.ɵɵelementStart(4, "button", 210);
|
|
1086
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_div_68_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
|
|
1087
|
+
i0.ɵɵelement(5, "i", 211);
|
|
1087
1088
|
i0.ɵɵelementEnd()();
|
|
1088
|
-
i0.ɵɵelementStart(6, "div",
|
|
1089
|
+
i0.ɵɵelementStart(6, "div", 212)(7, "div", 213)(8, "span");
|
|
1089
1090
|
i0.ɵɵtext(9, "Refresh");
|
|
1090
1091
|
i0.ɵɵelementEnd();
|
|
1091
|
-
i0.ɵɵelementStart(10, "span",
|
|
1092
|
+
i0.ɵɵelementStart(10, "span", 214)(11, "kbd");
|
|
1092
1093
|
i0.ɵɵtext(12, "Cmd");
|
|
1093
1094
|
i0.ɵɵelementEnd();
|
|
1094
1095
|
i0.ɵɵelementStart(13, "kbd");
|
|
1095
1096
|
i0.ɵɵtext(14, "R");
|
|
1096
1097
|
i0.ɵɵelementEnd()()();
|
|
1097
|
-
i0.ɵɵelementStart(15, "div",
|
|
1098
|
+
i0.ɵɵelementStart(15, "div", 213)(16, "span");
|
|
1098
1099
|
i0.ɵɵtext(17, "Run Test");
|
|
1099
1100
|
i0.ɵɵelementEnd();
|
|
1100
|
-
i0.ɵɵelementStart(18, "span",
|
|
1101
|
+
i0.ɵɵelementStart(18, "span", 214)(19, "kbd");
|
|
1101
1102
|
i0.ɵɵtext(20, "Cmd");
|
|
1102
1103
|
i0.ɵɵelementEnd();
|
|
1103
1104
|
i0.ɵɵelementStart(21, "kbd");
|
|
1104
1105
|
i0.ɵɵtext(22, "Enter");
|
|
1105
1106
|
i0.ɵɵelementEnd()()();
|
|
1106
|
-
i0.ɵɵelementStart(23, "div",
|
|
1107
|
+
i0.ɵɵelementStart(23, "div", 213)(24, "span");
|
|
1107
1108
|
i0.ɵɵtext(25, "Switch Tabs");
|
|
1108
1109
|
i0.ɵɵelementEnd();
|
|
1109
|
-
i0.ɵɵelementStart(26, "span",
|
|
1110
|
+
i0.ɵɵelementStart(26, "span", 214)(27, "kbd");
|
|
1110
1111
|
i0.ɵɵtext(28, "1");
|
|
1111
1112
|
i0.ɵɵelementEnd();
|
|
1112
1113
|
i0.ɵɵtext(29, "-");
|
|
@@ -1117,13 +1118,14 @@ function TestFormComponentExtended_div_56_Template(rf, ctx) { if (rf & 1) {
|
|
|
1117
1118
|
/** Settings key for keyboard shortcuts visibility */
|
|
1118
1119
|
const SHORTCUTS_SETTINGS_KEY = '__mj.Testing.ShowKeyboardShortcuts';
|
|
1119
1120
|
let TestFormComponentExtended = class TestFormComponentExtended extends TestFormComponent {
|
|
1120
|
-
constructor(elementRef, sharedService, router, route, cdr, testingDialogService, evalPrefsService, viewContainerRef) {
|
|
1121
|
+
constructor(elementRef, sharedService, router, route, cdr, testingDialogService, evalPrefsService, viewContainerRef, appManager) {
|
|
1121
1122
|
super(elementRef, sharedService, router, route, cdr);
|
|
1122
1123
|
this.router = router;
|
|
1123
1124
|
this.cdr = cdr;
|
|
1124
1125
|
this.testingDialogService = testingDialogService;
|
|
1125
1126
|
this.evalPrefsService = evalPrefsService;
|
|
1126
1127
|
this.viewContainerRef = viewContainerRef;
|
|
1128
|
+
this.appManager = appManager;
|
|
1127
1129
|
this.destroy$ = new Subject();
|
|
1128
1130
|
// UI state
|
|
1129
1131
|
this.activeTab = 'overview';
|
|
@@ -1460,6 +1462,12 @@ let TestFormComponentExtended = class TestFormComponentExtended extends TestForm
|
|
|
1460
1462
|
openTestSuite(suiteId) {
|
|
1461
1463
|
SharedService.Instance.OpenEntityRecord('MJ: Test Suites', CompositeKey.FromID(suiteId));
|
|
1462
1464
|
}
|
|
1465
|
+
navigateToTestingDashboard() {
|
|
1466
|
+
const testingApp = this.appManager.GetAppByName('Testing');
|
|
1467
|
+
if (testingApp) {
|
|
1468
|
+
this.navigationService.SwitchToApp(testingApp.ID);
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1463
1471
|
async runTest() {
|
|
1464
1472
|
if (this.record?.ID) {
|
|
1465
1473
|
this.testingDialogService.OpenTestDialog(this.record.ID, this.viewContainerRef);
|
|
@@ -1824,81 +1832,94 @@ let TestFormComponentExtended = class TestFormComponentExtended extends TestForm
|
|
|
1824
1832
|
console.warn('Failed to save shortcuts setting:', error);
|
|
1825
1833
|
}
|
|
1826
1834
|
}
|
|
1827
|
-
static { this.ɵfac = function TestFormComponentExtended_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestFormComponentExtended)(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)); }; }
|
|
1835
|
+
static { this.ɵfac = function TestFormComponentExtended_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestFormComponentExtended)(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), i0.ɵɵdirectiveInject(i4.ApplicationManager)); }; }
|
|
1828
1836
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestFormComponentExtended, selectors: [["mj-test-form"]], hostBindings: function TestFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
|
|
1829
1837
|
i0.ɵɵlistener("keydown", function TestFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, false, i0.ɵɵresolveDocument);
|
|
1830
|
-
} }, features: [i0.ɵɵInheritDefinitionFeature], decls:
|
|
1831
|
-
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "
|
|
1832
|
-
i0.ɵɵ
|
|
1838
|
+
} }, features: [i0.ɵɵInheritDefinitionFeature], decls: 69, vars: 37, consts: [["kendoDialogContainer", "", 1, "test-form"], [1, "test-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "fas", "fa-flask"], [1, "header-content"], [1, "header-left"], [1, "test-icon"], [1, "test-info"], [1, "test-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], ["class", "test-type", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "themeColor", "primary", 3, "click"], [1, "fas", "fa-play"], ["kendoButton", "", 3, "click", "disabled"], ["class", "test-description", 4, "ngIf"], ["class", "metrics-bar", 4, "ngIf"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-sliders-h"], [1, "fas", "fa-history"], ["class", "tab-badge", 4, "ngIf"], [1, "fas", "fa-layer-group"], [1, "fas", "fa-chart-line"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "config-tab", 4, "ngIf"], ["class", "runs-tab", 4, "ngIf"], ["class", "suites-tab", 4, "ngIf"], ["class", "history-tab", 4, "ngIf"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], ["class", "keyboard-shortcuts", 4, "ngIf"], [1, "test-type"], [1, "fas", "fa-tag"], [1, "test-description"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-label"], [1, "metric-value"], [1, "metric-progress"], [1, "metric-progress-fill"], [1, "tab-badge"], [1, "overview-tab"], [1, "info-section"], [1, "fas", "fa-info-circle"], [1, "info-grid"], [1, "info-item"], [1, "info-label"], [1, "info-value"], [1, "status-badge-inline", 3, "ngClass"], [1, "json-section"], [1, "fas", "fa-code"], [1, "json-tabs"], [1, "json-tab", 3, "click"], [1, "fas", "fa-sign-in-alt"], [1, "fas", "fa-check-double"], [1, "fas", "fa-cog"], [1, "fas", "fa-tags"], [1, "code-editor-container"], ["language", "json", 3, "value", "readonly", "toolbar", "lineWrapping"], [1, "config-tab"], [1, "config-section"], [1, "fas", "fa-cogs"], [1, "config-grid"], [1, "config-item"], ["type", "number", "placeholder", "Lower = Higher Priority", 1, "config-input", 3, "ngModelChange", "ngModel"], ["type", "number", "min", "1", 1, "config-input", 3, "ngModelChange", "ngModel"], ["type", "number", 1, "config-input", 3, "ngModelChange", "ngModel"], ["type", "number", "step", "0.000001", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-item", "full-width"], ["type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-hint"], [1, "config-editor-container"], ["language", "json", 3, "change", "value", "readonly", "lineWrapping"], [1, "config-editor-container", "small"], [1, "runs-tab"], ["class", "loading-state", 4, "ngIf"], ["class", "runs-list", 4, "ngIf"], ["class", "empty-state", 4, "ngIf"], [1, "loading-state"], [1, "skeleton-list"], ["class", "skeleton-card", 4, "ngFor", "ngForOf"], [1, "skeleton-card"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "runs-list"], ["class", "run-item", 3, "click", 4, "ngFor", "ngForOf"], [1, "run-item", 3, "click"], [1, "run-icon"], [1, "fas"], [1, "run-content"], [1, "run-header"], [1, "run-id"], [1, "run-status"], [1, "run-meta"], [1, "fas", "fa-calendar"], [4, "ngIf"], [3, "entityName", "recordId", 4, "ngIf"], [1, "run-eval-stack"], ["class", "eval-pill status-pill", 3, "ngClass", "title", 4, "ngIf"], ["class", "run-tags", 4, "ngIf"], [1, "fas", "fa-chevron-right"], [1, "fas", "fa-clock"], [1, "fas", "fa-dollar-sign"], [3, "entityName", "recordId"], [1, "eval-pill", "status-pill", 3, "ngClass", "title"], ["class", "eval-pill human-pill no-feedback", "title", "Human Review: No rating submitted yet", 4, "ngIf"], ["class", "eval-pill human-pill has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title", 4, "ngIf"], ["title", "Human Review: No rating submitted yet", 1, "eval-pill", "human-pill", "no-feedback"], [1, "fas", "fa-user-slash"], [1, "eval-pill", "human-pill", "has-feedback", 3, "title"], [1, "fas", "fa-user"], ["class", "eval-pill auto-pill no-score", "title", "Auto Score: No automated score available", 4, "ngIf"], ["class", "eval-pill auto-pill has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title", 4, "ngIf"], ["title", "Auto Score: No automated score available", 1, "eval-pill", "auto-pill", "no-score"], [1, "fas", "fa-robot"], [1, "eval-pill", "auto-pill", "has-score", 3, "title"], [1, "run-tags"], ["class", "run-tag", 4, "ngFor", "ngForOf"], ["class", "run-tag-more", 4, "ngIf"], [1, "run-tag"], [1, "run-tag-more"], [1, "empty-state"], [1, "empty-icon"], [1, "fas", "fa-play-circle"], [1, "suites-tab"], ["class", "suites-list", 4, "ngIf"], [1, "suites-list"], ["class", "suite-item", 3, "click", 4, "ngFor", "ngForOf"], [1, "suite-item", 3, "click"], [1, "suite-icon"], [1, "suite-content"], [1, "suite-name"], [1, "suite-meta"], [1, "fas", "fa-sort-numeric-up"], [1, "fas", "fa-folder-open"], [1, "history-tab"], ["class", "history-content", 4, "ngIf"], ["text", "Loading history..."], [1, "history-content"], [1, "history-filters"], [1, "time-range-filters"], [1, "filter-label"], [1, "filter-btn", 3, "click"], [1, "history-actions"], [1, "fas", "fa-download"], ["class", "history-kpi-cards", 4, "ngIf"], ["class", "history-section", 4, "ngIf"], [1, "history-kpi-cards"], [1, "kpi-card"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], ["class", "kpi-card", 4, "ngIf"], [1, "kpi-icon", "pass-rate"], [1, "fas", "fa-percentage"], [1, "fas", "trend-icon"], [1, "fas", "fa-star"], [1, "history-section"], [1, "fas", "fa-calendar-alt"], [1, "history-table-container"], [1, "history-table"], [4, "ngFor", "ngForOf"], [1, "date-cell"], [1, "runs-cell"], ["class", "passed-cell", 4, "ngIf"], ["class", "failed-cell", 4, "ngIf"], ["class", "pass-rate-cell", 4, "ngIf"], ["class", "score-cell", 4, "ngIf"], [1, "duration-cell"], [1, "cost-cell"], [1, "passed-cell"], [1, "failed-cell"], [1, "pass-rate-cell"], [1, "pass-rate-bar"], [1, "pass-rate-fill"], [1, "pass-rate-text"], [1, "score-cell"], [1, "suite-performance-list"], ["class", "suite-perf-card", 3, "click", 4, "ngFor", "ngForOf"], [1, "suite-perf-card", 3, "click"], [1, "suite-perf-header"], [1, "suite-perf-name"], ["class", "suite-perf-tags", 4, "ngIf"], [1, "suite-perf-stats"], [1, "suite-stat"], [1, "stat-value"], [1, "stat-label"], ["class", "suite-stat", 4, "ngIf"], [1, "fas", "fa-chevron-right", "suite-perf-arrow"], [1, "suite-perf-tags"], ["class", "tag-mini", 4, "ngFor", "ngForOf"], ["class", "tag-more", 4, "ngIf"], [1, "tag-mini"], [1, "tag-more"], [1, "stat-value", "pass-rate"], [1, "keyboard-shortcuts"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "fas", "fa-times"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"]], template: function TestFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
1839
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "nav", 2)(3, "ol")(4, "li")(5, "a", 3);
|
|
1840
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
|
|
1841
|
+
i0.ɵɵelement(6, "i", 4);
|
|
1842
|
+
i0.ɵɵelementStart(7, "span", 5);
|
|
1843
|
+
i0.ɵɵtext(8, "Testing");
|
|
1844
|
+
i0.ɵɵelementEnd()()();
|
|
1845
|
+
i0.ɵɵelementStart(9, "li", 6);
|
|
1846
|
+
i0.ɵɵelement(10, "i", 7)(11, "i", 8);
|
|
1847
|
+
i0.ɵɵelementStart(12, "span");
|
|
1848
|
+
i0.ɵɵtext(13);
|
|
1849
|
+
i0.ɵɵelementEnd()()()();
|
|
1850
|
+
i0.ɵɵelementStart(14, "div", 9)(15, "div", 10)(16, "div", 11);
|
|
1851
|
+
i0.ɵɵelement(17, "i", 8);
|
|
1833
1852
|
i0.ɵɵelementEnd();
|
|
1834
|
-
i0.ɵɵelementStart(
|
|
1835
|
-
i0.ɵɵtext(
|
|
1853
|
+
i0.ɵɵelementStart(18, "div", 12)(19, "h1");
|
|
1854
|
+
i0.ɵɵtext(20);
|
|
1836
1855
|
i0.ɵɵelementEnd();
|
|
1837
|
-
i0.ɵɵelementStart(
|
|
1838
|
-
i0.ɵɵelement(
|
|
1839
|
-
i0.ɵɵtext(
|
|
1856
|
+
i0.ɵɵelementStart(21, "div", 13)(22, "span", 14);
|
|
1857
|
+
i0.ɵɵelement(23, "i", 15);
|
|
1858
|
+
i0.ɵɵtext(24);
|
|
1840
1859
|
i0.ɵɵelementEnd();
|
|
1841
|
-
i0.ɵɵtemplate(
|
|
1860
|
+
i0.ɵɵtemplate(25, TestFormComponentExtended_span_25_Template, 3, 1, "span", 16);
|
|
1842
1861
|
i0.ɵɵelementEnd()()();
|
|
1843
|
-
i0.ɵɵelementStart(
|
|
1844
|
-
i0.ɵɵelement(
|
|
1845
|
-
i0.ɵɵelementStart(
|
|
1846
|
-
i0.ɵɵlistener("click", function
|
|
1847
|
-
i0.ɵɵelement(
|
|
1848
|
-
i0.ɵɵtext(
|
|
1862
|
+
i0.ɵɵelementStart(26, "div", 17);
|
|
1863
|
+
i0.ɵɵelement(27, "app-evaluation-mode-toggle");
|
|
1864
|
+
i0.ɵɵelementStart(28, "button", 18);
|
|
1865
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_28_listener() { return ctx.runTest(); });
|
|
1866
|
+
i0.ɵɵelement(29, "i", 19);
|
|
1867
|
+
i0.ɵɵtext(30, " Run Test ");
|
|
1849
1868
|
i0.ɵɵelementEnd();
|
|
1850
|
-
i0.ɵɵelementStart(
|
|
1851
|
-
i0.ɵɵlistener("click", function
|
|
1852
|
-
i0.ɵɵelement(
|
|
1853
|
-
i0.ɵɵtext(
|
|
1869
|
+
i0.ɵɵelementStart(31, "button", 20);
|
|
1870
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_31_listener() { return ctx.refresh(); });
|
|
1871
|
+
i0.ɵɵelement(32, "i", 15);
|
|
1872
|
+
i0.ɵɵtext(33);
|
|
1854
1873
|
i0.ɵɵelementEnd()()();
|
|
1855
|
-
i0.ɵɵtemplate(
|
|
1874
|
+
i0.ɵɵtemplate(34, TestFormComponentExtended_div_34_Template, 3, 1, "div", 21)(35, TestFormComponentExtended_div_35_Template, 23, 6, "div", 22);
|
|
1856
1875
|
i0.ɵɵelementEnd();
|
|
1857
|
-
i0.ɵɵelementStart(
|
|
1858
|
-
i0.ɵɵlistener("click", function
|
|
1859
|
-
i0.ɵɵelement(
|
|
1860
|
-
i0.ɵɵelementStart(
|
|
1861
|
-
i0.ɵɵtext(
|
|
1876
|
+
i0.ɵɵelementStart(36, "div", 23)(37, "div", 24)(38, "button", 25);
|
|
1877
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_38_listener() { return ctx.changeTab("overview"); });
|
|
1878
|
+
i0.ɵɵelement(39, "i", 26);
|
|
1879
|
+
i0.ɵɵelementStart(40, "span");
|
|
1880
|
+
i0.ɵɵtext(41, "Overview");
|
|
1862
1881
|
i0.ɵɵelementEnd()();
|
|
1863
|
-
i0.ɵɵelementStart(
|
|
1864
|
-
i0.ɵɵlistener("click", function
|
|
1865
|
-
i0.ɵɵelement(
|
|
1866
|
-
i0.ɵɵelementStart(
|
|
1867
|
-
i0.ɵɵtext(
|
|
1882
|
+
i0.ɵɵelementStart(42, "button", 25);
|
|
1883
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_42_listener() { return ctx.changeTab("config"); });
|
|
1884
|
+
i0.ɵɵelement(43, "i", 27);
|
|
1885
|
+
i0.ɵɵelementStart(44, "span");
|
|
1886
|
+
i0.ɵɵtext(45, "Configuration");
|
|
1868
1887
|
i0.ɵɵelementEnd()();
|
|
1869
|
-
i0.ɵɵelementStart(
|
|
1870
|
-
i0.ɵɵlistener("click", function
|
|
1871
|
-
i0.ɵɵelement(
|
|
1872
|
-
i0.ɵɵelementStart(
|
|
1873
|
-
i0.ɵɵtext(
|
|
1888
|
+
i0.ɵɵelementStart(46, "button", 25);
|
|
1889
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_46_listener() { return ctx.changeTab("runs"); });
|
|
1890
|
+
i0.ɵɵelement(47, "i", 28);
|
|
1891
|
+
i0.ɵɵelementStart(48, "span");
|
|
1892
|
+
i0.ɵɵtext(49, "Runs");
|
|
1874
1893
|
i0.ɵɵelementEnd();
|
|
1875
|
-
i0.ɵɵtemplate(
|
|
1894
|
+
i0.ɵɵtemplate(50, TestFormComponentExtended_span_50_Template, 2, 1, "span", 29);
|
|
1876
1895
|
i0.ɵɵelementEnd();
|
|
1877
|
-
i0.ɵɵelementStart(
|
|
1878
|
-
i0.ɵɵlistener("click", function
|
|
1879
|
-
i0.ɵɵelement(
|
|
1880
|
-
i0.ɵɵelementStart(
|
|
1881
|
-
i0.ɵɵtext(
|
|
1896
|
+
i0.ɵɵelementStart(51, "button", 25);
|
|
1897
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_51_listener() { return ctx.changeTab("suites"); });
|
|
1898
|
+
i0.ɵɵelement(52, "i", 30);
|
|
1899
|
+
i0.ɵɵelementStart(53, "span");
|
|
1900
|
+
i0.ɵɵtext(54, "Test Suites");
|
|
1882
1901
|
i0.ɵɵelementEnd();
|
|
1883
|
-
i0.ɵɵtemplate(
|
|
1902
|
+
i0.ɵɵtemplate(55, TestFormComponentExtended_span_55_Template, 2, 1, "span", 29);
|
|
1884
1903
|
i0.ɵɵelementEnd();
|
|
1885
|
-
i0.ɵɵelementStart(
|
|
1886
|
-
i0.ɵɵlistener("click", function
|
|
1887
|
-
i0.ɵɵelement(
|
|
1888
|
-
i0.ɵɵelementStart(
|
|
1889
|
-
i0.ɵɵtext(
|
|
1904
|
+
i0.ɵɵelementStart(56, "button", 25);
|
|
1905
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_56_listener() { return ctx.changeTab("analytics"); });
|
|
1906
|
+
i0.ɵɵelement(57, "i", 31);
|
|
1907
|
+
i0.ɵɵelementStart(58, "span");
|
|
1908
|
+
i0.ɵɵtext(59, "Analytics");
|
|
1890
1909
|
i0.ɵɵelementEnd()()()();
|
|
1891
|
-
i0.ɵɵelementStart(
|
|
1892
|
-
i0.ɵɵtemplate(
|
|
1910
|
+
i0.ɵɵelementStart(60, "div", 32);
|
|
1911
|
+
i0.ɵɵtemplate(61, TestFormComponentExtended_div_61_Template, 78, 29, "div", 33)(62, TestFormComponentExtended_div_62_Template, 52, 17, "div", 34)(63, TestFormComponentExtended_div_63_Template, 4, 3, "div", 35)(64, TestFormComponentExtended_div_64_Template, 4, 3, "div", 36)(65, TestFormComponentExtended_div_65_Template, 3, 2, "div", 37);
|
|
1893
1912
|
i0.ɵɵelementEnd();
|
|
1894
|
-
i0.ɵɵelementStart(
|
|
1895
|
-
i0.ɵɵlistener("click", function
|
|
1896
|
-
i0.ɵɵelement(
|
|
1913
|
+
i0.ɵɵelementStart(66, "button", 38);
|
|
1914
|
+
i0.ɵɵlistener("click", function TestFormComponentExtended_Template_button_click_66_listener() { return ctx.toggleShortcuts(); });
|
|
1915
|
+
i0.ɵɵelement(67, "i", 39);
|
|
1897
1916
|
i0.ɵɵelementEnd();
|
|
1898
|
-
i0.ɵɵtemplate(
|
|
1917
|
+
i0.ɵɵtemplate(68, TestFormComponentExtended_div_68_Template, 32, 0, "div", 40);
|
|
1899
1918
|
i0.ɵɵelementEnd();
|
|
1900
1919
|
} if (rf & 2) {
|
|
1901
|
-
i0.ɵɵadvance(
|
|
1920
|
+
i0.ɵɵadvance(13);
|
|
1921
|
+
i0.ɵɵtextInterpolate(ctx.record.Name);
|
|
1922
|
+
i0.ɵɵadvance(3);
|
|
1902
1923
|
i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
|
|
1903
1924
|
i0.ɵɵadvance(4);
|
|
1904
1925
|
i0.ɵɵtextInterpolate(ctx.record.Name);
|
|
@@ -1953,7 +1974,7 @@ let TestFormComponentExtended = class TestFormComponentExtended extends TestForm
|
|
|
1953
1974
|
i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
|
|
1954
1975
|
i0.ɵɵadvance(2);
|
|
1955
1976
|
i0.ɵɵproperty("ngIf", ctx.showShortcuts);
|
|
1956
|
-
} }, dependencies: [i4.NgClass, i4.NgForOf, i4.NgIf, i5.DefaultValueAccessor, i5.NumberValueAccessor, i5.NgControlStatus, i5.MinValidator, i5.NgModel, i6.DialogContainerDirective, i7.ButtonComponent, i8.CodeEditorComponent, i3.EvaluationModeToggleComponent, i9.LoadingComponent, i10.EntityLinkPillComponent, i4.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-primary-dark: #1d4ed8;\n --test-success: #10b981;\n --test-success-light: #d1fae5;\n --test-error: #ef4444;\n --test-error-light: #fee2e2;\n --test-warning: #f59e0b;\n --test-warning-light: #fef3c7;\n --test-disabled: #6b7280;\n --test-bg: #f8fafc;\n --test-surface: #ffffff;\n --test-border: #e2e8f0;\n --test-text: #1e293b;\n --test-text-secondary: #64748b;\n --test-text-muted: #94a3b8;\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --test-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n\n.test-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n\n.test-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n\n.test-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.test-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] { background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%); }\n.status-badge.status-disabled[_ngcontent-%COMP%] { background: linear-gradient(135deg, var(--test-disabled) 0%, #4b5563 100%); }\n.status-badge.status-pending[_ngcontent-%COMP%] { background: linear-gradient(135deg, var(--test-warning) 0%, #d97706 100%); }\n\n.status-badge-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: white;\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge-inline.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge-inline.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.test-type[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n\n\n.test-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: rgba(37, 99, 235, 0.15);\n color: var(--test-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.info-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n\n\n.json-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.json-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: rgba(0, 0, 0, 0.05);\n}\n\n.json-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n\n\n\n\n.config-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.config-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.config-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.config-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small[_ngcontent-%COMP%] {\n min-height: 100px;\n max-height: 150px;\n}\n\n\n\n\n\n.runs-tab[_ngcontent-%COMP%], \n.suites-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n.runs-list[_ngcontent-%COMP%], \n.suites-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover, \n.suite-item[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon[_ngcontent-%COMP%], \n.suite-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.run-content[_ngcontent-%COMP%], \n.suite-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n.run-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n\n\n.eval-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.eval-pill.status-pill.status-passed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.eval-pill.status-pill.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.status-pill.status-error[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-timeout[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-skipped[_ngcontent-%COMP%], \n.eval-pill.status-pill.status-pending[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-pill.status-pill.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #2563eb;\n}\n\n\n\n.eval-pill.human-pill.no-feedback[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.human-pill.has-feedback.rating-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.eval-pill.auto-pill.no-score[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.auto-pill.has-score.score-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.auto-pill.has-score.score-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.auto-pill.has-score.score-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\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: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\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\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(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--test-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}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\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: 768px) {\n .test-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-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 .test-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .json-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .json-tab[_ngcontent-%COMP%] {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-icon[_ngcontent-%COMP%], \n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta[_ngcontent-%COMP%], \n .suite-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 40px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .test-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .test-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .run-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .json-tab[_ngcontent-%COMP%], \n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item[_ngcontent-%COMP%]:active, \n .suite-item[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active, \n .json-tab[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n }\n\n \n\n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: #e2e8f0;\n }\n}\n\n\n\n\n\n.history-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.history-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n\n\n.history-filters[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--test-primary);\n color: white;\n border-color: var(--test-primary);\n}\n\n.history-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n.history-kpi-cards[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.trend-icon.trend-up[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n\n\n.history-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n.history-table-container[_ngcontent-%COMP%] {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.history-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.03);\n}\n\n.date-cell[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell[_ngcontent-%COMP%] {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell[_ngcontent-%COMP%] {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n min-width: 120px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text[_ngcontent-%COMP%] {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n\n\n.suite-performance-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.high[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.low[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover .suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n\n@media print {\n .test-form[_ngcontent-%COMP%] {\n background: white;\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%], \n .empty-state[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid #ddd;\n }\n}"], changeDetection: 0 }); }
|
|
1977
|
+
} }, dependencies: [i5.NgClass, i5.NgForOf, i5.NgIf, i6.DefaultValueAccessor, i6.NumberValueAccessor, i6.NgControlStatus, i6.MinValidator, i6.NgModel, i7.DialogContainerDirective, i8.ButtonComponent, i9.CodeEditorComponent, i3.EvaluationModeToggleComponent, i10.LoadingComponent, i11.EntityLinkPillComponent, i5.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-primary-dark: #1d4ed8;\n --test-success: #10b981;\n --test-success-light: #d1fae5;\n --test-error: #ef4444;\n --test-error-light: #fee2e2;\n --test-warning: #f59e0b;\n --test-warning-light: #fef3c7;\n --test-disabled: #6b7280;\n --test-bg: #f8fafc;\n --test-surface: #ffffff;\n --test-border: #e2e8f0;\n --test-text: #1e293b;\n --test-text-secondary: #64748b;\n --test-text-muted: #94a3b8;\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --test-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.1);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.test-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n\n.test-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n\n.test-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.test-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] { background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%); }\n.status-badge.status-disabled[_ngcontent-%COMP%] { background: linear-gradient(135deg, var(--test-disabled) 0%, #4b5563 100%); }\n.status-badge.status-pending[_ngcontent-%COMP%] { background: linear-gradient(135deg, var(--test-warning) 0%, #d97706 100%); }\n\n.status-badge-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: white;\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active[_ngcontent-%COMP%] { background: var(--test-success); }\n.status-badge-inline.status-disabled[_ngcontent-%COMP%] { background: var(--test-disabled); }\n.status-badge-inline.status-pending[_ngcontent-%COMP%] { background: var(--test-warning); }\n\n.test-type[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n\n\n.test-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: rgba(37, 99, 235, 0.15);\n color: var(--test-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.info-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.info-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n\n\n.json-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.json-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: rgba(0, 0, 0, 0.05);\n}\n\n.json-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.code-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n\n\n\n\n.config-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.config-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.config-item[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.config-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small[_ngcontent-%COMP%] {\n min-height: 100px;\n max-height: 150px;\n}\n\n\n\n\n\n.runs-tab[_ngcontent-%COMP%], \n.suites-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 0;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n.runs-list[_ngcontent-%COMP%], \n.suites-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover, \n.suite-item[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon[_ngcontent-%COMP%], \n.suite-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.run-content[_ngcontent-%COMP%], \n.suite-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.suite-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%] > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%], \n.suite-item[_ngcontent-%COMP%]:hover > i.fa-chevron-right[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n.run-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n\n\n.eval-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.eval-pill.status-pill.status-passed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.eval-pill.status-pill.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.status-pill.status-error[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-timeout[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-skipped[_ngcontent-%COMP%], \n.eval-pill.status-pill.status-pending[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-pill.status-pill.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #2563eb;\n}\n\n\n\n.eval-pill.human-pill.no-feedback[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.human-pill.has-feedback.rating-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.eval-pill.auto-pill.no-score[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.auto-pill.has-score.score-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.auto-pill.has-score.score-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.auto-pill.has-score.score-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\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: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\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\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(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: var(--test-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}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\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: 768px) {\n .test-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-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 .test-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .info-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .json-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .json-tab[_ngcontent-%COMP%] {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-icon[_ngcontent-%COMP%], \n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta[_ngcontent-%COMP%], \n .suite-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 40px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .test-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .test-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .run-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .json-tab[_ngcontent-%COMP%], \n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item[_ngcontent-%COMP%]:active, \n .suite-item[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active, \n .json-tab[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n }\n\n \n\n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .run-item[_ngcontent-%COMP%], \n .suite-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: #e2e8f0;\n }\n}\n\n\n\n\n\n.history-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.history-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n\n\n.history-filters[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--test-primary);\n color: white;\n border-color: var(--test-primary);\n}\n\n.history-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n.history-kpi-cards[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.trend-icon.trend-up[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n\n\n.history-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n.history-table-container[_ngcontent-%COMP%] {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.history-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.03);\n}\n\n.date-cell[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell[_ngcontent-%COMP%] {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell[_ngcontent-%COMP%] {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n min-width: 120px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill[_ngcontent-%COMP%] {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text[_ngcontent-%COMP%] {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n\n\n.suite-performance-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name[_ngcontent-%COMP%] {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.high[_ngcontent-%COMP%] {\n color: var(--test-success);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-value.pass-rate.low[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.suite-stat[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card[_ngcontent-%COMP%]:hover .suite-perf-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n\n@media print {\n .test-form[_ngcontent-%COMP%] {\n background: white;\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .info-section[_ngcontent-%COMP%], \n .json-section[_ngcontent-%COMP%], \n .config-section[_ngcontent-%COMP%], \n .empty-state[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid #ddd;\n }\n}"], changeDetection: 0 }); }
|
|
1957
1978
|
};
|
|
1958
1979
|
TestFormComponentExtended = __decorate([
|
|
1959
1980
|
RegisterClass(BaseFormComponent, 'MJ: Tests')
|
|
@@ -1961,12 +1982,12 @@ TestFormComponentExtended = __decorate([
|
|
|
1961
1982
|
export { TestFormComponentExtended };
|
|
1962
1983
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestFormComponentExtended, [{
|
|
1963
1984
|
type: Component,
|
|
1964
|
-
args: [{ selector: 'mj-test-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-form\" kendoDialogContainer>\n <!-- Header Section -->\n <div class=\"test-header\">\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"test-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <div class=\"test-info\">\n <h1>{{ record.Name }}</h1>\n <div class=\"test-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n <span class=\"test-type\" *ngIf=\"record.Type\">\n <i class=\"fas fa-tag\"></i>\n {{ record.Type }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button kendoButton (click)=\"runTest()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test\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 <!-- Test Description -->\n <div class=\"test-description\" *ngIf=\"record.Description\">\n <p>{{ record.Description }}</p>\n </div>\n\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\" *ngIf=\"testRunsLoaded && testRuns.length > 0\">\n <div class=\"metric-card\">\n <div class=\"metric-label\">Total Runs</div>\n <div class=\"metric-value\">{{ testRuns.length }}</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 class=\"metric-progress\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"getPassRate()\"></div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Cost</div>\n <div class=\"metric-value\">{{ formatCost(getAverageCost()) }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Duration</div>\n <div class=\"metric-value\">{{ formatDuration(getAverageDuration()) }}</div>\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>\n <span>Overview</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'config'\"\n (click)=\"changeTab('config')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'config'\">\n <i class=\"fas fa-sliders-h\"></i>\n <span>Configuration</span>\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-history\"></i>\n <span>Runs</span>\n <span class=\"tab-badge\" *ngIf=\"testRunsLoaded\">{{ testRuns.length }}</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'suites'\"\n (click)=\"changeTab('suites')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'suites'\">\n <i class=\"fas fa-layer-group\"></i>\n <span>Test Suites</span>\n <span class=\"tab-badge\" *ngIf=\"suiteTestsLoaded\">{{ suiteTests.length }}</span>\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 <i class=\"fas fa-chart-line\"></i>\n <span>Analytics</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 <!-- Basic Information -->\n <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Test Information</h3>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <div class=\"info-label\">Name</div>\n <div class=\"info-value\">{{ record.Name }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Type</div>\n <div class=\"info-value\">{{ record.Type || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Status</div>\n <div class=\"info-value\">\n <span class=\"status-badge-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Priority</div>\n <div class=\"info-value\">{{ record.Priority || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Duration</div>\n <div class=\"info-value\">{{ record.EstimatedDurationSeconds ? formatDuration(record.EstimatedDurationSeconds) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Cost</div>\n <div class=\"info-value\">{{ record.EstimatedCostUSD ? formatCost(record.EstimatedCostUSD) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Repeat Count</div>\n <div class=\"info-value\">{{ record.RepeatCount || 1 }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Max Execution Time</div>\n <div class=\"info-value\">{{ formatTimeout(record.MaxExecutionTimeMS) }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Created</div>\n <div class=\"info-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Updated</div>\n <div class=\"info-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n </div>\n </div>\n\n <!-- JSON Data Views -->\n <div class=\"json-section\">\n <h3><i class=\"fas fa-code\"></i> Test Definition</h3>\n <div class=\"json-tabs\">\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'input'\"\n (click)=\"setJsonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i>\n Input Definition\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'expected'\"\n (click)=\"setJsonView('expected')\">\n <i class=\"fas fa-check-double\"></i>\n Expected Outcomes\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'config'\"\n (click)=\"setJsonView('config')\">\n <i class=\"fas fa-cog\"></i>\n Configuration\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'tags'\"\n (click)=\"setJsonView('tags')\">\n <i class=\"fas fa-tags\"></i>\n Tags\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"getJsonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- Configuration Tab -->\n <div class=\"config-tab\" *ngIf=\"activeTab === 'config'\">\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n <div class=\"config-grid\">\n <div class=\"config-item\">\n <label>Priority</label>\n <input type=\"number\" [(ngModel)]=\"record.Priority\" class=\"config-input\" placeholder=\"Lower = Higher Priority\" />\n </div>\n <div class=\"config-item\">\n <label>Repeat Count</label>\n <input type=\"number\" [(ngModel)]=\"record.RepeatCount\" class=\"config-input\" min=\"1\" />\n </div>\n <div class=\"config-item\">\n <label>Estimated Duration (seconds)</label>\n <input type=\"number\" [(ngModel)]=\"record.EstimatedDurationSeconds\" class=\"config-input\" />\n </div>\n <div class=\"config-item\">\n <label>Estimated Cost (USD)</label>\n <input type=\"number\" step=\"0.000001\" [(ngModel)]=\"record.EstimatedCostUSD\" class=\"config-input\" />\n </div>\n <div class=\"config-item full-width\">\n <label>Max Execution Time (ms)</label>\n <input type=\"number\" [(ngModel)]=\"record.MaxExecutionTimeMS\" class=\"config-input\" placeholder=\"Default: 300000 (5 min)\" />\n <span class=\"config-hint\">Leave empty for default 5 minute timeout</span>\n </div>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-sign-in-alt\"></i> Input Definition (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.InputDefinition || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.InputDefinition = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-check-double\"></i> Expected Outcomes (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.ExpectedOutcomes || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.ExpectedOutcomes = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cog\"></i> Configuration (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.Configuration || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Configuration = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-tags\"></i> Tags (JSON Array)</h3>\n <div class=\"config-editor-container small\">\n <mj-code-editor\n [value]=\"record.Tags || '[]'\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Tags = $event\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- Test Runs Tab -->\n <div class=\"runs-tab\" *ngIf=\"activeTab === 'runs'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingRuns\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3,4,5]\">\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 <!-- Runs List -->\n <div class=\"runs-list\" *ngIf=\"!loadingRuns && testRuns.length > 0\">\n <div class=\"run-item\" *ngFor=\"let run of testRuns\" (click)=\"openTestRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-stopwatch]=\"run.Status === 'Timeout'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n <span *ngIf=\"run.DurationSeconds\"><i class=\"fas fa-clock\"></i> {{ formatDuration(run.DurationSeconds) }}</span>\n <span *ngIf=\"run.CostUSD\"><i class=\"fas fa-dollar-sign\"></i> {{ formatCost(run.CostUSD) }}</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 <!-- Evaluation indicators -->\n <div class=\"run-eval-stack\">\n <!-- Status indicator -->\n <span class=\"eval-pill status-pill\" *ngIf=\"evalPreferences.showExecution\"\n [ngClass]=\"'status-' + run.Status.toLowerCase()\"\n [title]=\"getStatusTooltip(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-hourglass-end]=\"run.Status === 'Timeout'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n <span>{{ run.Status }}</span>\n </span>\n <!-- Human feedback indicator -->\n <ng-container *ngIf=\"evalPreferences.showHuman\">\n <span class=\"eval-pill human-pill no-feedback\" *ngIf=\"!getFeedbackForRun(run.ID)?.Rating\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n <span class=\"eval-pill human-pill has-feedback\" *ngIf=\"getFeedbackForRun(run.ID)?.Rating as rating\"\n [class.rating-low]=\"rating <= 4\"\n [class.rating-medium]=\"rating >= 5 && rating <= 6\"\n [class.rating-good]=\"rating >= 7 && rating <= 8\"\n [class.rating-excellent]=\"rating >= 9\"\n [title]=\"getHumanTooltip(rating, getFeedbackForRun(run.ID)?.CorrectionSummary || getFeedbackForRun(run.ID)?.Comments || null)\">\n <i class=\"fas fa-user\"></i>\n <span>{{ rating }}</span>\n </span>\n </ng-container>\n <!-- Auto score indicator -->\n <ng-container *ngIf=\"evalPreferences.showAuto\">\n <span class=\"eval-pill auto-pill no-score\" *ngIf=\"run.Score == null\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n <span class=\"eval-pill auto-pill has-score\" *ngIf=\"run.Score != null\"\n [class.score-low]=\"run.Score < 0.5\"\n [class.score-medium]=\"run.Score >= 0.5 && run.Score < 0.7\"\n [class.score-good]=\"run.Score >= 0.7 && run.Score < 0.85\"\n [class.score-excellent]=\"run.Score >= 0.85\"\n [title]=\"'Auto Score: ' + (run.Score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ (run.Score * 100).toFixed(0) }}%</span>\n </span>\n </ng-container>\n </div>\n <div class=\"run-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"run-tag\" *ngFor=\"let tag of getRunTags(run).slice(0, 3)\">{{ tag }}</span>\n <span class=\"run-tag-more\" *ngIf=\"getRunTags(run).length > 3\">+{{ getRunTags(run).length - 3 }}</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"testRunsLoaded && !loadingRuns && testRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Test Runs Yet</h4>\n <p>Run this test to see execution history and results here.</p>\n <button kendoButton (click)=\"runTest()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\n </div>\n\n <!-- Test Suites Tab -->\n <div class=\"suites-tab\" *ngIf=\"activeTab === 'suites'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingSuites\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3]\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Suites List -->\n <div class=\"suites-list\" *ngIf=\"!loadingSuites && suiteTests.length > 0\">\n <div class=\"suite-item\" *ngFor=\"let suiteTest of suiteTests\" (click)=\"openTestSuite(suiteTest.SuiteID)\">\n <div class=\"suite-icon\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-content\">\n <div class=\"suite-name\">{{ suiteTest.Suite }}</div>\n <div class=\"suite-meta\">\n <span><i class=\"fas fa-sort-numeric-up\"></i> Sequence: {{ suiteTest.Sequence }}</span>\n <span *ngIf=\"suiteTest.Status\"><i class=\"fas fa-info-circle\"></i> {{ suiteTest.Status }}</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"suiteTestsLoaded && !loadingSuites && suiteTests.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-folder-open\"></i>\n </div>\n <h4>Not Part of Any Suite</h4>\n <p>This test is not included in any test suites. Add it to a suite to run it with other tests.</p>\n </div>\n </div>\n\n <!-- Analytics Tab -->\n <div class=\"history-tab\" *ngIf=\"activeTab === 'analytics'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingHistory\">\n <mj-loading text=\"Loading history...\"></mj-loading>\n </div>\n\n <!-- History Content -->\n <div class=\"history-content\" *ngIf=\"!loadingHistory && historyLoaded\">\n <!-- Filters -->\n <div class=\"history-filters\">\n <div class=\"time-range-filters\">\n <span class=\"filter-label\">Time Range:</span>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '7d'\"\n (click)=\"setHistoryTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '30d'\"\n (click)=\"setHistoryTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '90d'\"\n (click)=\"setHistoryTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === 'all'\"\n (click)=\"setHistoryTimeRange('all')\">All Time</button>\n </div>\n <div class=\"history-actions\">\n <button kendoButton (click)=\"exportHistoryToCSV()\" [disabled]=\"historyData.length === 0\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n\n <!-- KPI Cards -->\n <div class=\"history-kpi-cards\" *ngIf=\"historyData.length > 0\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\" *ngIf=\"evalPreferences.showExecution\">\n <div class=\"kpi-icon pass-rate\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">\n {{ getOverallPassRate().toFixed(1) }}%\n <i class=\"fas trend-icon\"\n [class.fa-arrow-up]=\"getPassRateTrend() === 'up'\"\n [class.fa-arrow-down]=\"getPassRateTrend() === 'down'\"\n [class.fa-minus]=\"getPassRateTrend() === 'stable'\"\n [class.trend-up]=\"getPassRateTrend() === 'up'\"\n [class.trend-down]=\"getPassRateTrend() === 'down'\"></i>\n </div>\n <div class=\"kpi-label\">Pass Rate</div>\n </div>\n </div>\n <div class=\"kpi-card\" *ngIf=\"evalPreferences.showAuto\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ (getOverallAvgScore() * 100).toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Score</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getOverallAvgDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getOverallAvgCost()) }}</div>\n <div class=\"kpi-label\">Avg Cost</div>\n </div>\n </div>\n </div>\n\n <!-- Daily History Table -->\n <div class=\"history-section\" *ngIf=\"historyData.length > 0\">\n <h3><i class=\"fas fa-calendar-alt\"></i> Daily Performance</h3>\n <div class=\"history-table-container\">\n <table class=\"history-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Runs</th>\n <th *ngIf=\"evalPreferences.showExecution\">Passed</th>\n <th *ngIf=\"evalPreferences.showExecution\">Failed</th>\n <th *ngIf=\"evalPreferences.showExecution\">Pass Rate</th>\n <th *ngIf=\"evalPreferences.showAuto\">Avg Score</th>\n <th>Avg Duration</th>\n <th>Avg Cost</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let day of historyData\">\n <td class=\"date-cell\">{{ day.date | date:'mediumDate' }}</td>\n <td class=\"runs-cell\">{{ day.runCount }}</td>\n <td class=\"passed-cell\" *ngIf=\"evalPreferences.showExecution\">{{ day.passCount }}</td>\n <td class=\"failed-cell\" *ngIf=\"evalPreferences.showExecution\">{{ day.failCount }}</td>\n <td class=\"pass-rate-cell\" *ngIf=\"evalPreferences.showExecution\">\n <div class=\"pass-rate-bar\">\n <div class=\"pass-rate-fill\" [style.width.%]=\"day.passRate\"></div>\n <span class=\"pass-rate-text\">{{ day.passRate.toFixed(1) }}%</span>\n </div>\n </td>\n <td class=\"score-cell\" *ngIf=\"evalPreferences.showAuto\">{{ (day.avgScore * 100).toFixed(1) }}%</td>\n <td class=\"duration-cell\">{{ formatDuration(day.avgDuration) }}</td>\n <td class=\"cost-cell\">{{ formatCost(day.avgCost) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Suite Performance -->\n <div class=\"history-section\" *ngIf=\"suitePerformance.length > 0\">\n <h3><i class=\"fas fa-layer-group\"></i> Performance by Suite</h3>\n <div class=\"suite-performance-list\">\n <div class=\"suite-perf-card\" *ngFor=\"let suite of suitePerformance\" (click)=\"openSuiteFromHistory(suite.suiteId)\">\n <div class=\"suite-perf-header\">\n <div class=\"suite-perf-name\">{{ suite.suiteName }}</div>\n <div class=\"suite-perf-tags\" *ngIf=\"suite.tags.length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of suite.tags.slice(0, 3)\">{{ tag }}</span>\n <span class=\"tag-more\" *ngIf=\"suite.tags.length > 3\">+{{ suite.tags.length - 3 }}</span>\n </div>\n </div>\n <div class=\"suite-perf-stats\">\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ suite.totalRuns }}</span>\n <span class=\"stat-label\">Runs</span>\n </div>\n <div class=\"suite-stat\" *ngIf=\"evalPreferences.showExecution\">\n <span class=\"stat-value pass-rate\" [class.high]=\"suite.passRate >= 80\" [class.low]=\"suite.passRate < 50\">\n {{ suite.passRate.toFixed(1) }}%\n </span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n <div class=\"suite-stat\" *ngIf=\"evalPreferences.showAuto\">\n <span class=\"stat-value\">{{ (suite.avgScore * 100).toFixed(1) }}%</span>\n <span class=\"stat-label\">Avg Score</span>\n </div>\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatDuration(suite.avgDuration) }}</span>\n <span class=\"stat-label\">Avg Duration</span>\n </div>\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatCost(suite.avgCost) }}</span>\n <span class=\"stat-label\">Avg Cost</span>\n </div>\n <div class=\"suite-stat\" *ngIf=\"suite.lastRun\">\n <span class=\"stat-value\">{{ getRelativeTime(suite.lastRun) }}</span>\n <span class=\"stat-label\">Last Run</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right suite-perf-arrow\"></i>\n </div>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"historyData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No History Available</h4>\n <p>Run this test to start building history and analytics data.</p>\n <button kendoButton (click)=\"runTest()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\n </div>\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>Run Test</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</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 Form - World-Class UX\n Premium Test Definition Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-primary-dark: #1d4ed8;\n --test-success: #10b981;\n --test-success-light: #d1fae5;\n --test-error: #ef4444;\n --test-error-light: #fee2e2;\n --test-warning: #f59e0b;\n --test-warning-light: #fef3c7;\n --test-disabled: #6b7280;\n --test-bg: #f8fafc;\n --test-surface: #ffffff;\n --test-border: #e2e8f0;\n --test-text: #1e293b;\n --test-text-secondary: #64748b;\n --test-text-muted: #94a3b8;\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --test-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Base Container */\n.test-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Test Icon */\n.test-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon:hover {\n transform: scale(1.05);\n}\n\n/* Test Info */\n.test-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active { background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%); }\n.status-badge.status-disabled { background: linear-gradient(135deg, var(--test-disabled) 0%, #4b5563 100%); }\n.status-badge.status-pending { background: linear-gradient(135deg, var(--test-warning) 0%, #d97706 100%); }\n\n.status-badge-inline {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: white;\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-type {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n/* Test Description */\n.test-description {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill {\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: rgba(37, 99, 235, 0.15);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Info Section */\n.info-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n/* JSON Section */\n.json-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section h3 i {\n color: var(--test-primary);\n}\n\n.json-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab:hover {\n color: var(--test-text);\n background: rgba(0, 0, 0, 0.05);\n}\n\n.json-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab i {\n font-size: 12px;\n}\n\n.code-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n/* ===========================\n Configuration Tab\n =========================== */\n.config-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section h3 i {\n color: var(--test-primary);\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width {\n grid-column: 1 / -1;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.config-input::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small {\n min-height: 100px;\n max-height: 150px;\n}\n\n/* ===========================\n Runs Tab\n =========================== */\n.runs-tab,\n.suites-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Loading States & Skeletons */\n.loading-state {\n padding: 0;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Runs List */\n.runs-list,\n.suites-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item,\n.suite-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item:hover,\n.suite-item:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon,\n.suite-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.run-content,\n.suite-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta,\n.suite-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta span,\n.suite-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta span i,\n.suite-meta span i {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item > i.fa-chevron-right,\n.suite-item > i.fa-chevron-right {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item:hover > i.fa-chevron-right,\n.suite-item:hover > i.fa-chevron-right {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Run Evaluation Stack */\n.run-eval-stack {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n/* Evaluation Pills */\n.eval-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill i {\n font-size: 10px;\n}\n\n/* Status pill colors */\n.eval-pill.status-pill.status-passed {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.eval-pill.status-pill.status-failed {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.status-pill.status-error {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-timeout {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-skipped,\n.eval-pill.status-pill.status-pending {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-pill.status-pill.status-running {\n background: #dbeafe;\n color: #2563eb;\n}\n\n/* Human feedback pills */\n.eval-pill.human-pill.no-feedback {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.human-pill.has-feedback.rating-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Auto score pills */\n.eval-pill.auto-pill.no-score {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.auto-pill.has-score.score-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.auto-pill.has-score.score-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.auto-pill.has-score.score-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Run Tags */\n.run-tags {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n/* ===========================\n Empty States\n =========================== */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* Legacy no-data for backwards compatibility */\n.no-data {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\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/* ===========================\n Keyboard Shortcuts Popup\n =========================== */\n/* Keyboard shortcuts toggle button */\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(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-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}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid {\n grid-template-columns: 1fr;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n .test-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-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 .test-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info h1 {\n font-size: 18px;\n }\n\n .test-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-shortcut {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .info-section,\n .json-section,\n .config-section {\n padding: 18px;\n }\n\n .info-grid {\n grid-template-columns: 1fr;\n }\n\n .json-tabs {\n flex-direction: column;\n }\n\n .json-tab {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item,\n .suite-item {\n padding: 14px;\n }\n\n .run-icon,\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta,\n .suite-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n .empty-state {\n padding: 40px 20px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\n }\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .test-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .run-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .json-tab,\n .run-item,\n .suite-item {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item:active,\n .suite-item:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab:active,\n .json-tab:active {\n background: rgba(37, 99, 235, 0.1);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .run-item,\n .suite-item {\n min-height: 64px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-line {\n animation: none;\n background: #e2e8f0;\n }\n}\n\n/* ===========================\n History Tab\n =========================== */\n.history-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.history-content {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n/* History Filters */\n.history-filters {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n color: white;\n border-color: var(--test-primary);\n}\n\n.history-actions {\n display: flex;\n gap: 8px;\n}\n\n/* KPI Cards */\n.history-kpi-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate {\n background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon {\n font-size: 14px;\n}\n\n.trend-icon.trend-up {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down {\n color: var(--test-error);\n}\n\n/* History Section */\n.history-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section h3 i {\n color: var(--test-primary);\n}\n\n/* History Table */\n.history-table-container {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table th,\n.history-table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table th {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table tbody tr:hover {\n background: rgba(37, 99, 235, 0.03);\n}\n\n.date-cell {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell {\n min-width: 120px;\n}\n\n.pass-rate-bar {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n/* Suite Performance List */\n.suite-performance-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat .stat-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat .stat-value.pass-rate.high {\n color: var(--test-success);\n}\n\n.suite-stat .stat-value.pass-rate.low {\n color: var(--test-error);\n}\n\n.suite-stat .stat-label {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover .suite-perf-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-form {\n background: white;\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .keyboard-shortcuts {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .info-section,\n .json-section,\n .config-section,\n .empty-state {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid #ddd;\n }\n}\n"] }]
|
|
1965
|
-
}], () => [{ 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: [{
|
|
1985
|
+
args: [{ selector: 'mj-test-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-form\" kendoDialogContainer>\n <!-- Header Section -->\n <div class=\"test-header\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <i class=\"fas fa-flask\"></i>\n <span>{{ record.Name }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"test-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <div class=\"test-info\">\n <h1>{{ record.Name }}</h1>\n <div class=\"test-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n <span class=\"test-type\" *ngIf=\"record.Type\">\n <i class=\"fas fa-tag\"></i>\n {{ record.Type }}\n </span>\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n <button kendoButton (click)=\"runTest()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test\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 <!-- Test Description -->\n <div class=\"test-description\" *ngIf=\"record.Description\">\n <p>{{ record.Description }}</p>\n </div>\n\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\" *ngIf=\"testRunsLoaded && testRuns.length > 0\">\n <div class=\"metric-card\">\n <div class=\"metric-label\">Total Runs</div>\n <div class=\"metric-value\">{{ testRuns.length }}</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 class=\"metric-progress\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"getPassRate()\"></div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Cost</div>\n <div class=\"metric-value\">{{ formatCost(getAverageCost()) }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Avg Duration</div>\n <div class=\"metric-value\">{{ formatDuration(getAverageDuration()) }}</div>\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>\n <span>Overview</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'config'\"\n (click)=\"changeTab('config')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'config'\">\n <i class=\"fas fa-sliders-h\"></i>\n <span>Configuration</span>\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-history\"></i>\n <span>Runs</span>\n <span class=\"tab-badge\" *ngIf=\"testRunsLoaded\">{{ testRuns.length }}</span>\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'suites'\"\n (click)=\"changeTab('suites')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'suites'\">\n <i class=\"fas fa-layer-group\"></i>\n <span>Test Suites</span>\n <span class=\"tab-badge\" *ngIf=\"suiteTestsLoaded\">{{ suiteTests.length }}</span>\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 <i class=\"fas fa-chart-line\"></i>\n <span>Analytics</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 <!-- Basic Information -->\n <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Test Information</h3>\n <div class=\"info-grid\">\n <div class=\"info-item\">\n <div class=\"info-label\">Name</div>\n <div class=\"info-value\">{{ record.Name }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Type</div>\n <div class=\"info-value\">{{ record.Type || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Status</div>\n <div class=\"info-value\">\n <span class=\"status-badge-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Priority</div>\n <div class=\"info-value\">{{ record.Priority || 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Duration</div>\n <div class=\"info-value\">{{ record.EstimatedDurationSeconds ? formatDuration(record.EstimatedDurationSeconds) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Estimated Cost</div>\n <div class=\"info-value\">{{ record.EstimatedCostUSD ? formatCost(record.EstimatedCostUSD) : 'N/A' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Repeat Count</div>\n <div class=\"info-value\">{{ record.RepeatCount || 1 }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Max Execution Time</div>\n <div class=\"info-value\">{{ formatTimeout(record.MaxExecutionTimeMS) }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Created</div>\n <div class=\"info-value\">{{ record.__mj_CreatedAt | date:'medium' }}</div>\n </div>\n <div class=\"info-item\">\n <div class=\"info-label\">Updated</div>\n <div class=\"info-value\">{{ record.__mj_UpdatedAt | date:'medium' }}</div>\n </div>\n </div>\n </div>\n\n <!-- JSON Data Views -->\n <div class=\"json-section\">\n <h3><i class=\"fas fa-code\"></i> Test Definition</h3>\n <div class=\"json-tabs\">\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'input'\"\n (click)=\"setJsonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i>\n Input Definition\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'expected'\"\n (click)=\"setJsonView('expected')\">\n <i class=\"fas fa-check-double\"></i>\n Expected Outcomes\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'config'\"\n (click)=\"setJsonView('config')\">\n <i class=\"fas fa-cog\"></i>\n Configuration\n </button>\n <button class=\"json-tab\"\n [class.active]=\"activeJsonView === 'tags'\"\n (click)=\"setJsonView('tags')\">\n <i class=\"fas fa-tags\"></i>\n Tags\n </button>\n </div>\n <div class=\"code-editor-container\">\n <mj-code-editor\n [value]=\"getJsonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- Configuration Tab -->\n <div class=\"config-tab\" *ngIf=\"activeTab === 'config'\">\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cogs\"></i> Execution Settings</h3>\n <div class=\"config-grid\">\n <div class=\"config-item\">\n <label>Priority</label>\n <input type=\"number\" [(ngModel)]=\"record.Priority\" class=\"config-input\" placeholder=\"Lower = Higher Priority\" />\n </div>\n <div class=\"config-item\">\n <label>Repeat Count</label>\n <input type=\"number\" [(ngModel)]=\"record.RepeatCount\" class=\"config-input\" min=\"1\" />\n </div>\n <div class=\"config-item\">\n <label>Estimated Duration (seconds)</label>\n <input type=\"number\" [(ngModel)]=\"record.EstimatedDurationSeconds\" class=\"config-input\" />\n </div>\n <div class=\"config-item\">\n <label>Estimated Cost (USD)</label>\n <input type=\"number\" step=\"0.000001\" [(ngModel)]=\"record.EstimatedCostUSD\" class=\"config-input\" />\n </div>\n <div class=\"config-item full-width\">\n <label>Max Execution Time (ms)</label>\n <input type=\"number\" [(ngModel)]=\"record.MaxExecutionTimeMS\" class=\"config-input\" placeholder=\"Default: 300000 (5 min)\" />\n <span class=\"config-hint\">Leave empty for default 5 minute timeout</span>\n </div>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-sign-in-alt\"></i> Input Definition (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.InputDefinition || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.InputDefinition = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-check-double\"></i> Expected Outcomes (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.ExpectedOutcomes || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.ExpectedOutcomes = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-cog\"></i> Configuration (JSON)</h3>\n <div class=\"config-editor-container\">\n <mj-code-editor\n [value]=\"record.Configuration || ''\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Configuration = $event\">\n </mj-code-editor>\n </div>\n </div>\n\n <div class=\"config-section\">\n <h3><i class=\"fas fa-tags\"></i> Tags (JSON Array)</h3>\n <div class=\"config-editor-container small\">\n <mj-code-editor\n [value]=\"record.Tags || '[]'\"\n language=\"json\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"record.Tags = $event\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- Test Runs Tab -->\n <div class=\"runs-tab\" *ngIf=\"activeTab === 'runs'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingRuns\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3,4,5]\">\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 <!-- Runs List -->\n <div class=\"runs-list\" *ngIf=\"!loadingRuns && testRuns.length > 0\">\n <div class=\"run-item\" *ngFor=\"let run of testRuns\" (click)=\"openTestRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-stopwatch]=\"run.Status === 'Timeout'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header\">\n <span class=\"run-id\">Run #{{ run.ID.substring(0, 8) }}</span>\n <span class=\"run-status\" [style.color]=\"getRunStatusColor(run.Status)\">{{ run.Status }}</span>\n </div>\n <div class=\"run-meta\">\n <span><i class=\"fas fa-calendar\"></i> {{ getRelativeTime(run.StartedAt) }}</span>\n <span *ngIf=\"run.DurationSeconds\"><i class=\"fas fa-clock\"></i> {{ formatDuration(run.DurationSeconds) }}</span>\n <span *ngIf=\"run.CostUSD\"><i class=\"fas fa-dollar-sign\"></i> {{ formatCost(run.CostUSD) }}</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 <!-- Evaluation indicators -->\n <div class=\"run-eval-stack\">\n <!-- Status indicator -->\n <span class=\"eval-pill status-pill\" *ngIf=\"evalPreferences.showExecution\"\n [ngClass]=\"'status-' + run.Status.toLowerCase()\"\n [title]=\"getStatusTooltip(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Passed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-exclamation]=\"run.Status === 'Error'\"\n [class.fa-hourglass-end]=\"run.Status === 'Timeout'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"></i>\n <span>{{ run.Status }}</span>\n </span>\n <!-- Human feedback indicator -->\n <ng-container *ngIf=\"evalPreferences.showHuman\">\n <span class=\"eval-pill human-pill no-feedback\" *ngIf=\"!getFeedbackForRun(run.ID)?.Rating\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n <span class=\"eval-pill human-pill has-feedback\" *ngIf=\"getFeedbackForRun(run.ID)?.Rating as rating\"\n [class.rating-low]=\"rating <= 4\"\n [class.rating-medium]=\"rating >= 5 && rating <= 6\"\n [class.rating-good]=\"rating >= 7 && rating <= 8\"\n [class.rating-excellent]=\"rating >= 9\"\n [title]=\"getHumanTooltip(rating, getFeedbackForRun(run.ID)?.CorrectionSummary || getFeedbackForRun(run.ID)?.Comments || null)\">\n <i class=\"fas fa-user\"></i>\n <span>{{ rating }}</span>\n </span>\n </ng-container>\n <!-- Auto score indicator -->\n <ng-container *ngIf=\"evalPreferences.showAuto\">\n <span class=\"eval-pill auto-pill no-score\" *ngIf=\"run.Score == null\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n <span class=\"eval-pill auto-pill has-score\" *ngIf=\"run.Score != null\"\n [class.score-low]=\"run.Score < 0.5\"\n [class.score-medium]=\"run.Score >= 0.5 && run.Score < 0.7\"\n [class.score-good]=\"run.Score >= 0.7 && run.Score < 0.85\"\n [class.score-excellent]=\"run.Score >= 0.85\"\n [title]=\"'Auto Score: ' + (run.Score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ (run.Score * 100).toFixed(0) }}%</span>\n </span>\n </ng-container>\n </div>\n <div class=\"run-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"run-tag\" *ngFor=\"let tag of getRunTags(run).slice(0, 3)\">{{ tag }}</span>\n <span class=\"run-tag-more\" *ngIf=\"getRunTags(run).length > 3\">+{{ getRunTags(run).length - 3 }}</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"testRunsLoaded && !loadingRuns && testRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Test Runs Yet</h4>\n <p>Run this test to see execution history and results here.</p>\n <button kendoButton (click)=\"runTest()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\n </div>\n\n <!-- Test Suites Tab -->\n <div class=\"suites-tab\" *ngIf=\"activeTab === 'suites'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingSuites\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3]\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Suites List -->\n <div class=\"suites-list\" *ngIf=\"!loadingSuites && suiteTests.length > 0\">\n <div class=\"suite-item\" *ngFor=\"let suiteTest of suiteTests\" (click)=\"openTestSuite(suiteTest.SuiteID)\">\n <div class=\"suite-icon\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-content\">\n <div class=\"suite-name\">{{ suiteTest.Suite }}</div>\n <div class=\"suite-meta\">\n <span><i class=\"fas fa-sort-numeric-up\"></i> Sequence: {{ suiteTest.Sequence }}</span>\n <span *ngIf=\"suiteTest.Status\"><i class=\"fas fa-info-circle\"></i> {{ suiteTest.Status }}</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"suiteTestsLoaded && !loadingSuites && suiteTests.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-folder-open\"></i>\n </div>\n <h4>Not Part of Any Suite</h4>\n <p>This test is not included in any test suites. Add it to a suite to run it with other tests.</p>\n </div>\n </div>\n\n <!-- Analytics Tab -->\n <div class=\"history-tab\" *ngIf=\"activeTab === 'analytics'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingHistory\">\n <mj-loading text=\"Loading history...\"></mj-loading>\n </div>\n\n <!-- History Content -->\n <div class=\"history-content\" *ngIf=\"!loadingHistory && historyLoaded\">\n <!-- Filters -->\n <div class=\"history-filters\">\n <div class=\"time-range-filters\">\n <span class=\"filter-label\">Time Range:</span>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '7d'\"\n (click)=\"setHistoryTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '30d'\"\n (click)=\"setHistoryTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === '90d'\"\n (click)=\"setHistoryTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\"\n [class.active]=\"historyTimeRange === 'all'\"\n (click)=\"setHistoryTimeRange('all')\">All Time</button>\n </div>\n <div class=\"history-actions\">\n <button kendoButton (click)=\"exportHistoryToCSV()\" [disabled]=\"historyData.length === 0\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n\n <!-- KPI Cards -->\n <div class=\"history-kpi-cards\" *ngIf=\"historyData.length > 0\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getTotalRuns() }}</div>\n <div class=\"kpi-label\">Total Runs</div>\n </div>\n </div>\n <div class=\"kpi-card\" *ngIf=\"evalPreferences.showExecution\">\n <div class=\"kpi-icon pass-rate\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">\n {{ getOverallPassRate().toFixed(1) }}%\n <i class=\"fas trend-icon\"\n [class.fa-arrow-up]=\"getPassRateTrend() === 'up'\"\n [class.fa-arrow-down]=\"getPassRateTrend() === 'down'\"\n [class.fa-minus]=\"getPassRateTrend() === 'stable'\"\n [class.trend-up]=\"getPassRateTrend() === 'up'\"\n [class.trend-down]=\"getPassRateTrend() === 'down'\"></i>\n </div>\n <div class=\"kpi-label\">Pass Rate</div>\n </div>\n </div>\n <div class=\"kpi-card\" *ngIf=\"evalPreferences.showAuto\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ (getOverallAvgScore() * 100).toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Score</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getOverallAvgDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getOverallAvgCost()) }}</div>\n <div class=\"kpi-label\">Avg Cost</div>\n </div>\n </div>\n </div>\n\n <!-- Daily History Table -->\n <div class=\"history-section\" *ngIf=\"historyData.length > 0\">\n <h3><i class=\"fas fa-calendar-alt\"></i> Daily Performance</h3>\n <div class=\"history-table-container\">\n <table class=\"history-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Runs</th>\n <th *ngIf=\"evalPreferences.showExecution\">Passed</th>\n <th *ngIf=\"evalPreferences.showExecution\">Failed</th>\n <th *ngIf=\"evalPreferences.showExecution\">Pass Rate</th>\n <th *ngIf=\"evalPreferences.showAuto\">Avg Score</th>\n <th>Avg Duration</th>\n <th>Avg Cost</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let day of historyData\">\n <td class=\"date-cell\">{{ day.date | date:'mediumDate' }}</td>\n <td class=\"runs-cell\">{{ day.runCount }}</td>\n <td class=\"passed-cell\" *ngIf=\"evalPreferences.showExecution\">{{ day.passCount }}</td>\n <td class=\"failed-cell\" *ngIf=\"evalPreferences.showExecution\">{{ day.failCount }}</td>\n <td class=\"pass-rate-cell\" *ngIf=\"evalPreferences.showExecution\">\n <div class=\"pass-rate-bar\">\n <div class=\"pass-rate-fill\" [style.width.%]=\"day.passRate\"></div>\n <span class=\"pass-rate-text\">{{ day.passRate.toFixed(1) }}%</span>\n </div>\n </td>\n <td class=\"score-cell\" *ngIf=\"evalPreferences.showAuto\">{{ (day.avgScore * 100).toFixed(1) }}%</td>\n <td class=\"duration-cell\">{{ formatDuration(day.avgDuration) }}</td>\n <td class=\"cost-cell\">{{ formatCost(day.avgCost) }}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Suite Performance -->\n <div class=\"history-section\" *ngIf=\"suitePerformance.length > 0\">\n <h3><i class=\"fas fa-layer-group\"></i> Performance by Suite</h3>\n <div class=\"suite-performance-list\">\n <div class=\"suite-perf-card\" *ngFor=\"let suite of suitePerformance\" (click)=\"openSuiteFromHistory(suite.suiteId)\">\n <div class=\"suite-perf-header\">\n <div class=\"suite-perf-name\">{{ suite.suiteName }}</div>\n <div class=\"suite-perf-tags\" *ngIf=\"suite.tags.length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of suite.tags.slice(0, 3)\">{{ tag }}</span>\n <span class=\"tag-more\" *ngIf=\"suite.tags.length > 3\">+{{ suite.tags.length - 3 }}</span>\n </div>\n </div>\n <div class=\"suite-perf-stats\">\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ suite.totalRuns }}</span>\n <span class=\"stat-label\">Runs</span>\n </div>\n <div class=\"suite-stat\" *ngIf=\"evalPreferences.showExecution\">\n <span class=\"stat-value pass-rate\" [class.high]=\"suite.passRate >= 80\" [class.low]=\"suite.passRate < 50\">\n {{ suite.passRate.toFixed(1) }}%\n </span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n <div class=\"suite-stat\" *ngIf=\"evalPreferences.showAuto\">\n <span class=\"stat-value\">{{ (suite.avgScore * 100).toFixed(1) }}%</span>\n <span class=\"stat-label\">Avg Score</span>\n </div>\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatDuration(suite.avgDuration) }}</span>\n <span class=\"stat-label\">Avg Duration</span>\n </div>\n <div class=\"suite-stat\">\n <span class=\"stat-value\">{{ formatCost(suite.avgCost) }}</span>\n <span class=\"stat-label\">Avg Cost</span>\n </div>\n <div class=\"suite-stat\" *ngIf=\"suite.lastRun\">\n <span class=\"stat-value\">{{ getRelativeTime(suite.lastRun) }}</span>\n <span class=\"stat-label\">Last Run</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right suite-perf-arrow\"></i>\n </div>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"historyData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No History Available</h4>\n <p>Run this test to start building history and analytics data.</p>\n <button kendoButton (click)=\"runTest()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Test Now\n </button>\n </div>\n </div>\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>Run Test</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Enter</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 Form - World-Class UX\n Premium Test Definition Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-primary-dark: #1d4ed8;\n --test-success: #10b981;\n --test-success-light: #d1fae5;\n --test-error: #ef4444;\n --test-error-light: #fee2e2;\n --test-warning: #f59e0b;\n --test-warning-light: #fef3c7;\n --test-disabled: #6b7280;\n --test-bg: #f8fafc;\n --test-surface: #ffffff;\n --test-border: #e2e8f0;\n --test-text: #1e293b;\n --test-text-secondary: #64748b;\n --test-text-muted: #94a3b8;\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --test-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 6px;\n transition: background 0.15s;\n}\n\n.breadcrumb a:hover {\n background: rgba(37, 99, 235, 0.1);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Base Container */\n.test-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 16px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Test Icon */\n.test-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.test-icon:hover {\n transform: scale(1.05);\n}\n\n/* Test Info */\n.test-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.status-badge.status-active { background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%); }\n.status-badge.status-disabled { background: linear-gradient(135deg, var(--test-disabled) 0%, #4b5563 100%); }\n.status-badge.status-pending { background: linear-gradient(135deg, var(--test-warning) 0%, #d97706 100%); }\n\n.status-badge-inline {\n display: inline-flex;\n align-items: center;\n padding: 2px 10px;\n border-radius: 10px;\n color: white;\n font-size: 11px;\n font-weight: 600;\n}\n\n.status-badge-inline.status-active { background: var(--test-success); }\n.status-badge-inline.status-disabled { background: var(--test-disabled); }\n.status-badge-inline.status-pending { background: var(--test-warning); }\n\n.test-type {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n padding: 4px 10px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n/* Test Description */\n.test-description {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n margin-bottom: 16px;\n border: 1px solid var(--test-border);\n}\n\n.test-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\n gap: 12px;\n}\n\n.metric-card {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n text-align: center;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 6px;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 8px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.metric-progress-fill {\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: rgba(37, 99, 235, 0.15);\n color: var(--test-primary);\n}\n\n.tab-shortcut {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Info Section */\n.info-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.info-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.info-section h3 i {\n color: var(--test-primary);\n}\n\n.info-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n}\n\n.info-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.info-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.info-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n/* JSON Section */\n.json-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-section h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.json-section h3 i {\n color: var(--test-primary);\n}\n\n.json-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n flex-wrap: wrap;\n}\n\n.json-tab {\n flex: 1;\n min-width: 100px;\n padding: 10px 14px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.json-tab:hover {\n color: var(--test-text);\n background: rgba(0, 0, 0, 0.05);\n}\n\n.json-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.json-tab i {\n font-size: 12px;\n}\n\n.code-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n max-height: 400px;\n}\n\n/* ===========================\n Configuration Tab\n =========================== */\n.config-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.config-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.config-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.config-section h3 i {\n color: var(--test-primary);\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.config-item.full-width {\n grid-column: 1 / -1;\n}\n\n.config-item label {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n}\n\n.config-input {\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n font-size: 14px;\n transition: var(--test-transition);\n background: var(--test-surface);\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--test-primary);\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.config-input::placeholder {\n color: var(--test-text-muted);\n}\n\n.config-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 4px;\n}\n\n.config-editor-container {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n min-height: 200px;\n}\n\n.config-editor-container.small {\n min-height: 100px;\n max-height: 150px;\n}\n\n/* ===========================\n Runs Tab\n =========================== */\n.runs-tab,\n.suites-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Loading States & Skeletons */\n.loading-state {\n padding: 0;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n flex-shrink: 0;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Runs List */\n.runs-list,\n.suites-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.run-item,\n.suite-item {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-item:hover,\n.suite-item:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.run-icon,\n.suite-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.suite-icon {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n}\n\n.run-content,\n.suite-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-id {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.suite-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-meta,\n.suite-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-meta span,\n.suite-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-meta span i,\n.suite-meta span i {\n color: var(--test-text-muted);\n font-size: 11px;\n}\n\n.run-item > i.fa-chevron-right,\n.suite-item > i.fa-chevron-right {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.run-item:hover > i.fa-chevron-right,\n.suite-item:hover > i.fa-chevron-right {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Run Evaluation Stack */\n.run-eval-stack {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n/* Evaluation Pills */\n.eval-pill {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border-radius: 16px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.eval-pill i {\n font-size: 10px;\n}\n\n/* Status pill colors */\n.eval-pill.status-pill.status-passed {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.eval-pill.status-pill.status-failed {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.status-pill.status-error {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-timeout {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.status-pill.status-skipped,\n.eval-pill.status-pill.status-pending {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-pill.status-pill.status-running {\n background: #dbeafe;\n color: #2563eb;\n}\n\n/* Human feedback pills */\n.eval-pill.human-pill.no-feedback {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.human-pill.has-feedback.rating-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.human-pill.has-feedback.rating-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.human-pill.has-feedback.rating-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.human-pill.has-feedback.rating-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Auto score pills */\n.eval-pill.auto-pill.no-score {\n background: #f1f5f9;\n color: #94a3b8;\n padding: 4px 8px;\n}\n\n.eval-pill.auto-pill.has-score.score-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.eval-pill.auto-pill.has-score.score-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.eval-pill.auto-pill.has-score.score-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.eval-pill.auto-pill.has-score.score-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Run Tags */\n.run-tags {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-top: 8px;\n flex-wrap: wrap;\n}\n\n.run-tag {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.run-tag-more {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n/* ===========================\n Empty States\n =========================== */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* Legacy no-data for backwards compatibility */\n.no-data {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: var(--test-text-muted);\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\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/* ===========================\n Keyboard Shortcuts Popup\n =========================== */\n/* Keyboard shortcuts toggle button */\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(--test-surface);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-md);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--test-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--test-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--test-primary);\n border-color: var(--test-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 12px 16px;\n box-shadow: var(--test-shadow-lg);\n font-size: 12px;\n color: var(--test-text-secondary);\n z-index: 100;\n max-width: 260px;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--test-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--test-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--test-text);\n background: var(--test-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}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\n.shortcut-keys kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .info-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .config-grid {\n grid-template-columns: 1fr;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n .test-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-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 .test-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-info h1 {\n font-size: 18px;\n }\n\n .test-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-shortcut {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .info-section,\n .json-section,\n .config-section {\n padding: 18px;\n }\n\n .info-grid {\n grid-template-columns: 1fr;\n }\n\n .json-tabs {\n flex-direction: column;\n }\n\n .json-tab {\n min-width: 0;\n justify-content: flex-start;\n }\n\n .run-item,\n .suite-item {\n padding: 14px;\n }\n\n .run-icon,\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .run-meta,\n .suite-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n .empty-state {\n padding: 40px 20px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\n }\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .test-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .run-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .json-tab,\n .run-item,\n .suite-item {\n -webkit-tap-highlight-color: transparent;\n }\n\n .run-item:active,\n .suite-item:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab:active,\n .json-tab:active {\n background: rgba(37, 99, 235, 0.1);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .run-item,\n .suite-item {\n min-height: 64px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-line {\n animation: none;\n background: #e2e8f0;\n }\n}\n\n/* ===========================\n History Tab\n =========================== */\n.history-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.history-content {\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n/* History Filters */\n.history-filters {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n}\n\n.time-range-filters {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n margin-right: 4px;\n}\n\n.filter-btn {\n padding: 8px 16px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n background: var(--test-surface);\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.filter-btn:hover {\n border-color: var(--test-primary-light);\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.filter-btn.active {\n background: var(--test-primary);\n color: white;\n border-color: var(--test-primary);\n}\n\n.history-actions {\n display: flex;\n gap: 8px;\n}\n\n/* KPI Cards */\n.history-kpi-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 16px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 18px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.kpi-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.kpi-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n border-radius: var(--test-radius-md);\n color: white;\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.kpi-icon.pass-rate {\n background: linear-gradient(135deg, var(--test-success) 0%, #059669 100%);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 22px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-top: 2px;\n}\n\n.trend-icon {\n font-size: 14px;\n}\n\n.trend-icon.trend-up {\n color: var(--test-success);\n}\n\n.trend-icon.trend-down {\n color: var(--test-error);\n}\n\n/* History Section */\n.history-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.history-section h3 {\n margin: 0 0 20px 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.history-section h3 i {\n color: var(--test-primary);\n}\n\n/* History Table */\n.history-table-container {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.history-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n}\n\n.history-table th,\n.history-table td {\n padding: 12px 16px;\n text-align: left;\n border-bottom: 1px solid var(--test-border);\n}\n\n.history-table th {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n}\n\n.history-table tbody tr:hover {\n background: rgba(37, 99, 235, 0.03);\n}\n\n.date-cell {\n font-weight: 600;\n color: var(--test-text);\n}\n\n.passed-cell {\n color: var(--test-success);\n font-weight: 600;\n}\n\n.failed-cell {\n color: var(--test-error);\n font-weight: 600;\n}\n\n.pass-rate-cell {\n min-width: 120px;\n}\n\n.pass-rate-bar {\n position: relative;\n height: 24px;\n background: var(--test-bg);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.pass-rate-fill {\n position: absolute;\n left: 0;\n top: 0;\n height: 100%;\n background: linear-gradient(90deg, var(--test-success) 0%, #34d399 100%);\n border-radius: 12px;\n transition: width 0.5s ease-out;\n}\n\n.pass-rate-text {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 700;\n color: var(--test-text);\n z-index: 1;\n}\n\n/* Suite Performance List */\n.suite-performance-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.suite-perf-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 18px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.suite-perf-header {\n flex: 1;\n min-width: 0;\n}\n\n.suite-perf-name {\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n}\n\n.suite-perf-tags {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.tag-more {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--test-border);\n color: var(--test-text-muted);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n}\n\n.suite-perf-stats {\n display: flex;\n gap: 24px;\n flex-wrap: wrap;\n}\n\n.suite-stat {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 2px;\n}\n\n.suite-stat .stat-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.suite-stat .stat-value.pass-rate.high {\n color: var(--test-success);\n}\n\n.suite-stat .stat-value.pass-rate.low {\n color: var(--test-error);\n}\n\n.suite-stat .stat-label {\n font-size: 10px;\n color: var(--test-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.suite-perf-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.suite-perf-card:hover .suite-perf-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-form {\n background: white;\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .keyboard-shortcuts {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .info-section,\n .json-section,\n .config-section,\n .empty-state {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid #ddd;\n }\n}\n"] }]
|
|
1986
|
+
}], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i3.TestingDialogService }, { type: i3.EvaluationPreferencesService }, { type: i0.ViewContainerRef }, { type: i4.ApplicationManager }], { handleKeyboardShortcut: [{
|
|
1966
1987
|
type: HostListener,
|
|
1967
1988
|
args: ['document:keydown', ['$event']]
|
|
1968
1989
|
}] }); })();
|
|
1969
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestFormComponentExtended, { className: "TestFormComponentExtended", filePath: "src/lib/custom/Tests/test-form.component.ts", lineNumber:
|
|
1990
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestFormComponentExtended, { className: "TestFormComponentExtended", filePath: "src/lib/custom/Tests/test-form.component.ts", lineNumber: 62 }); })();
|
|
1970
1991
|
export function LoadTestFormComponentExtended() {
|
|
1971
1992
|
// Prevents tree-shaking
|
|
1972
1993
|
}
|