@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,11 +19,12 @@ 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 "@
|
|
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-shared-generic";
|
|
27
28
|
const _c0 = ["chartContainer"];
|
|
28
29
|
const _c1 = () => [1, 2, 3, 4, 5];
|
|
29
30
|
const _c2 = () => [1, 2, 3];
|
|
@@ -33,9 +34,9 @@ const _c5 = (a0, a1, a2) => ({ "high": a0, "medium": a1, "low": a2 });
|
|
|
33
34
|
const _c6 = (a0, a1) => ({ "positive": a0, "negative": a1 });
|
|
34
35
|
const _c7 = (a0, a1, a2) => ({ "fa-arrow-down": a0, "fa-arrow-up": a1, "fa-minus": a2 });
|
|
35
36
|
const _c8 = (a0, a1) => ({ "improved": a0, "regressed": a1 });
|
|
36
|
-
function
|
|
37
|
-
i0.ɵɵelementStart(0, "span",
|
|
38
|
-
i0.ɵɵelement(1, "i",
|
|
37
|
+
function TestSuiteFormComponentExtended_span_25_Template(rf, ctx) { if (rf & 1) {
|
|
38
|
+
i0.ɵɵelementStart(0, "span", 43);
|
|
39
|
+
i0.ɵɵelement(1, "i", 29);
|
|
39
40
|
i0.ɵɵtext(2);
|
|
40
41
|
i0.ɵɵelementEnd();
|
|
41
42
|
} if (rf & 2) {
|
|
@@ -43,8 +44,8 @@ function TestSuiteFormComponentExtended_span_13_Template(rf, ctx) { if (rf & 1)
|
|
|
43
44
|
i0.ɵɵadvance(2);
|
|
44
45
|
i0.ɵɵtextInterpolate1(" ", ctx_r0.suiteTests.length, " tests ");
|
|
45
46
|
} }
|
|
46
|
-
function
|
|
47
|
-
i0.ɵɵelementStart(0, "div",
|
|
47
|
+
function TestSuiteFormComponentExtended_div_37_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
+
i0.ɵɵelementStart(0, "div", 44)(1, "p");
|
|
48
49
|
i0.ɵɵtext(2);
|
|
49
50
|
i0.ɵɵelementEnd()();
|
|
50
51
|
} if (rf & 2) {
|
|
@@ -52,8 +53,8 @@ function TestSuiteFormComponentExtended_div_25_Template(rf, ctx) { if (rf & 1) {
|
|
|
52
53
|
i0.ɵɵadvance(2);
|
|
53
54
|
i0.ɵɵtextInterpolate(ctx_r0.record.Description);
|
|
54
55
|
} }
|
|
55
|
-
function
|
|
56
|
-
i0.ɵɵelementStart(0, "span",
|
|
56
|
+
function TestSuiteFormComponentExtended_span_46_Template(rf, ctx) { if (rf & 1) {
|
|
57
|
+
i0.ɵɵelementStart(0, "span", 45);
|
|
57
58
|
i0.ɵɵtext(1);
|
|
58
59
|
i0.ɵɵelementEnd();
|
|
59
60
|
} if (rf & 2) {
|
|
@@ -61,8 +62,8 @@ function TestSuiteFormComponentExtended_span_34_Template(rf, ctx) { if (rf & 1)
|
|
|
61
62
|
i0.ɵɵadvance();
|
|
62
63
|
i0.ɵɵtextInterpolate(ctx_r0.suiteTests.length);
|
|
63
64
|
} }
|
|
64
|
-
function
|
|
65
|
-
i0.ɵɵelementStart(0, "span",
|
|
65
|
+
function TestSuiteFormComponentExtended_span_50_Template(rf, ctx) { if (rf & 1) {
|
|
66
|
+
i0.ɵɵelementStart(0, "span", 45);
|
|
66
67
|
i0.ɵɵtext(1);
|
|
67
68
|
i0.ɵɵelementEnd();
|
|
68
69
|
} if (rf & 2) {
|
|
@@ -70,55 +71,55 @@ function TestSuiteFormComponentExtended_span_38_Template(rf, ctx) { if (rf & 1)
|
|
|
70
71
|
i0.ɵɵadvance();
|
|
71
72
|
i0.ɵɵtextInterpolate(ctx_r0.suiteRuns.length);
|
|
72
73
|
} }
|
|
73
|
-
function
|
|
74
|
+
function TestSuiteFormComponentExtended_div_58_Template(rf, ctx) { if (rf & 1) {
|
|
74
75
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
75
|
-
i0.ɵɵelementStart(0, "div",
|
|
76
|
-
i0.ɵɵelement(3, "i",
|
|
76
|
+
i0.ɵɵelementStart(0, "div", 46)(1, "div", 47)(2, "h3");
|
|
77
|
+
i0.ɵɵelement(3, "i", 48);
|
|
77
78
|
i0.ɵɵtext(4, " Suite Information");
|
|
78
79
|
i0.ɵɵelementEnd();
|
|
79
|
-
i0.ɵɵelementStart(5, "div",
|
|
80
|
+
i0.ɵɵelementStart(5, "div", 49)(6, "div", 50)(7, "div", 51);
|
|
80
81
|
i0.ɵɵtext(8, "Name");
|
|
81
82
|
i0.ɵɵelementEnd();
|
|
82
|
-
i0.ɵɵelementStart(9, "div",
|
|
83
|
+
i0.ɵɵelementStart(9, "div", 52);
|
|
83
84
|
i0.ɵɵtext(10);
|
|
84
85
|
i0.ɵɵelementEnd()();
|
|
85
|
-
i0.ɵɵelementStart(11, "div",
|
|
86
|
+
i0.ɵɵelementStart(11, "div", 50)(12, "div", 51);
|
|
86
87
|
i0.ɵɵtext(13, "Status");
|
|
87
88
|
i0.ɵɵelementEnd();
|
|
88
|
-
i0.ɵɵelementStart(14, "div",
|
|
89
|
+
i0.ɵɵelementStart(14, "div", 52)(15, "span", 53);
|
|
89
90
|
i0.ɵɵtext(16);
|
|
90
91
|
i0.ɵɵelementEnd()()();
|
|
91
|
-
i0.ɵɵelementStart(17, "div",
|
|
92
|
+
i0.ɵɵelementStart(17, "div", 50)(18, "div", 51);
|
|
92
93
|
i0.ɵɵtext(19, "Created");
|
|
93
94
|
i0.ɵɵelementEnd();
|
|
94
|
-
i0.ɵɵelementStart(20, "div",
|
|
95
|
+
i0.ɵɵelementStart(20, "div", 52);
|
|
95
96
|
i0.ɵɵtext(21);
|
|
96
97
|
i0.ɵɵpipe(22, "date");
|
|
97
98
|
i0.ɵɵelementEnd()();
|
|
98
|
-
i0.ɵɵelementStart(23, "div",
|
|
99
|
+
i0.ɵɵelementStart(23, "div", 50)(24, "div", 51);
|
|
99
100
|
i0.ɵɵtext(25, "Updated");
|
|
100
101
|
i0.ɵɵelementEnd();
|
|
101
|
-
i0.ɵɵelementStart(26, "div",
|
|
102
|
+
i0.ɵɵelementStart(26, "div", 52);
|
|
102
103
|
i0.ɵɵtext(27);
|
|
103
104
|
i0.ɵɵpipe(28, "date");
|
|
104
105
|
i0.ɵɵelementEnd()();
|
|
105
|
-
i0.ɵɵelementStart(29, "div",
|
|
106
|
+
i0.ɵɵelementStart(29, "div", 50)(30, "div", 51);
|
|
106
107
|
i0.ɵɵtext(31, "Max Execution Time");
|
|
107
108
|
i0.ɵɵelementEnd();
|
|
108
|
-
i0.ɵɵelementStart(32, "div",
|
|
109
|
+
i0.ɵɵelementStart(32, "div", 52);
|
|
109
110
|
i0.ɵɵtext(33);
|
|
110
111
|
i0.ɵɵelementEnd()()()();
|
|
111
|
-
i0.ɵɵelementStart(34, "div",
|
|
112
|
-
i0.ɵɵelement(36, "i",
|
|
112
|
+
i0.ɵɵelementStart(34, "div", 54)(35, "h3");
|
|
113
|
+
i0.ɵɵelement(36, "i", 55);
|
|
113
114
|
i0.ɵɵtext(37, " Execution Settings");
|
|
114
115
|
i0.ɵɵelementEnd();
|
|
115
|
-
i0.ɵɵelementStart(38, "div",
|
|
116
|
+
i0.ɵɵelementStart(38, "div", 56)(39, "div", 57)(40, "label");
|
|
116
117
|
i0.ɵɵtext(41, "Max Execution Time (ms)");
|
|
117
118
|
i0.ɵɵelementEnd();
|
|
118
|
-
i0.ɵɵelementStart(42, "input",
|
|
119
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
119
|
+
i0.ɵɵelementStart(42, "input", 58);
|
|
120
|
+
i0.ɵɵtwoWayListener("ngModelChange", function TestSuiteFormComponentExtended_div_58_Template_input_ngModelChange_42_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.record.MaxExecutionTimeMS, $event) || (ctx_r0.record.MaxExecutionTimeMS = $event); return i0.ɵɵresetView($event); });
|
|
120
121
|
i0.ɵɵelementEnd();
|
|
121
|
-
i0.ɵɵelementStart(43, "span",
|
|
122
|
+
i0.ɵɵelementStart(43, "span", 59);
|
|
122
123
|
i0.ɵɵtext(44, "Default timeout for tests in this suite");
|
|
123
124
|
i0.ɵɵelementEnd()()()()();
|
|
124
125
|
} if (rf & 2) {
|
|
@@ -138,24 +139,24 @@ function TestSuiteFormComponentExtended_div_46_Template(rf, ctx) { if (rf & 1) {
|
|
|
138
139
|
i0.ɵɵadvance(9);
|
|
139
140
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r0.record.MaxExecutionTimeMS);
|
|
140
141
|
} }
|
|
141
|
-
function
|
|
142
|
-
i0.ɵɵelementStart(0, "div",
|
|
143
|
-
i0.ɵɵelement(1, "div",
|
|
144
|
-
i0.ɵɵelementStart(3, "div",
|
|
145
|
-
i0.ɵɵelement(4, "div",
|
|
142
|
+
function TestSuiteFormComponentExtended_div_59_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
143
|
+
i0.ɵɵelementStart(0, "div", 67);
|
|
144
|
+
i0.ɵɵelement(1, "div", 68)(2, "div", 69);
|
|
145
|
+
i0.ɵɵelementStart(3, "div", 70);
|
|
146
|
+
i0.ɵɵelement(4, "div", 71)(5, "div", 72);
|
|
146
147
|
i0.ɵɵelementEnd()();
|
|
147
148
|
} }
|
|
148
|
-
function
|
|
149
|
-
i0.ɵɵelementStart(0, "div",
|
|
150
|
-
i0.ɵɵtemplate(2,
|
|
149
|
+
function TestSuiteFormComponentExtended_div_59_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
150
|
+
i0.ɵɵelementStart(0, "div", 64)(1, "div", 65);
|
|
151
|
+
i0.ɵɵtemplate(2, TestSuiteFormComponentExtended_div_59_div_1_div_2_Template, 6, 0, "div", 66);
|
|
151
152
|
i0.ɵɵelementEnd()();
|
|
152
153
|
} if (rf & 2) {
|
|
153
154
|
i0.ɵɵadvance(2);
|
|
154
155
|
i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c1));
|
|
155
156
|
} }
|
|
156
|
-
function
|
|
157
|
+
function TestSuiteFormComponentExtended_div_59_div_2_div_1_span_9_Template(rf, ctx) { if (rf & 1) {
|
|
157
158
|
i0.ɵɵelementStart(0, "span");
|
|
158
|
-
i0.ɵɵelement(1, "i",
|
|
159
|
+
i0.ɵɵelement(1, "i", 48);
|
|
159
160
|
i0.ɵɵtext(2);
|
|
160
161
|
i0.ɵɵelementEnd();
|
|
161
162
|
} if (rf & 2) {
|
|
@@ -163,23 +164,23 @@ function TestSuiteFormComponentExtended_div_47_div_2_div_1_span_9_Template(rf, c
|
|
|
163
164
|
i0.ɵɵadvance(2);
|
|
164
165
|
i0.ɵɵtextInterpolate1(" ", test_r4.Status, "");
|
|
165
166
|
} }
|
|
166
|
-
function
|
|
167
|
+
function TestSuiteFormComponentExtended_div_59_div_2_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
167
168
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
168
|
-
i0.ɵɵelementStart(0, "div",
|
|
169
|
-
i0.ɵɵlistener("click", function
|
|
170
|
-
i0.ɵɵelementStart(1, "div",
|
|
169
|
+
i0.ɵɵelementStart(0, "div", 75);
|
|
170
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_59_div_2_div_1_Template_div_click_0_listener() { const test_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openTest(test_r4.TestID)); });
|
|
171
|
+
i0.ɵɵelementStart(1, "div", 76);
|
|
171
172
|
i0.ɵɵtext(2);
|
|
172
173
|
i0.ɵɵelementEnd();
|
|
173
|
-
i0.ɵɵelementStart(3, "div",
|
|
174
|
-
i0.ɵɵelement(4, "i",
|
|
174
|
+
i0.ɵɵelementStart(3, "div", 77);
|
|
175
|
+
i0.ɵɵelement(4, "i", 29);
|
|
175
176
|
i0.ɵɵelementEnd();
|
|
176
|
-
i0.ɵɵelementStart(5, "div",
|
|
177
|
+
i0.ɵɵelementStart(5, "div", 78)(6, "div", 79);
|
|
177
178
|
i0.ɵɵtext(7);
|
|
178
179
|
i0.ɵɵelementEnd();
|
|
179
|
-
i0.ɵɵelementStart(8, "div",
|
|
180
|
-
i0.ɵɵtemplate(9,
|
|
180
|
+
i0.ɵɵelementStart(8, "div", 80);
|
|
181
|
+
i0.ɵɵtemplate(9, TestSuiteFormComponentExtended_div_59_div_2_div_1_span_9_Template, 3, 1, "span", 81);
|
|
181
182
|
i0.ɵɵelementEnd()();
|
|
182
|
-
i0.ɵɵelement(10, "i",
|
|
183
|
+
i0.ɵɵelement(10, "i", 82);
|
|
183
184
|
i0.ɵɵelementEnd();
|
|
184
185
|
} if (rf & 2) {
|
|
185
186
|
const test_r4 = ctx.$implicit;
|
|
@@ -190,18 +191,18 @@ function TestSuiteFormComponentExtended_div_47_div_2_div_1_Template(rf, ctx) { i
|
|
|
190
191
|
i0.ɵɵadvance(2);
|
|
191
192
|
i0.ɵɵproperty("ngIf", test_r4.Status);
|
|
192
193
|
} }
|
|
193
|
-
function
|
|
194
|
-
i0.ɵɵelementStart(0, "div",
|
|
195
|
-
i0.ɵɵtemplate(1,
|
|
194
|
+
function TestSuiteFormComponentExtended_div_59_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
195
|
+
i0.ɵɵelementStart(0, "div", 73);
|
|
196
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_59_div_2_div_1_Template, 11, 3, "div", 74);
|
|
196
197
|
i0.ɵɵelementEnd();
|
|
197
198
|
} if (rf & 2) {
|
|
198
199
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
199
200
|
i0.ɵɵadvance();
|
|
200
201
|
i0.ɵɵproperty("ngForOf", ctx_r0.suiteTests);
|
|
201
202
|
} }
|
|
202
|
-
function
|
|
203
|
-
i0.ɵɵelementStart(0, "div",
|
|
204
|
-
i0.ɵɵelement(2, "i",
|
|
203
|
+
function TestSuiteFormComponentExtended_div_59_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
204
|
+
i0.ɵɵelementStart(0, "div", 83)(1, "div", 84);
|
|
205
|
+
i0.ɵɵelement(2, "i", 29);
|
|
205
206
|
i0.ɵɵelementEnd();
|
|
206
207
|
i0.ɵɵelementStart(3, "h4");
|
|
207
208
|
i0.ɵɵtext(4, "No Tests in Suite");
|
|
@@ -210,9 +211,9 @@ function TestSuiteFormComponentExtended_div_47_div_3_Template(rf, ctx) { if (rf
|
|
|
210
211
|
i0.ɵɵtext(6, "Add tests to this suite to start running them together.");
|
|
211
212
|
i0.ɵɵelementEnd()();
|
|
212
213
|
} }
|
|
213
|
-
function
|
|
214
|
-
i0.ɵɵelementStart(0, "div",
|
|
215
|
-
i0.ɵɵtemplate(1,
|
|
214
|
+
function TestSuiteFormComponentExtended_div_59_Template(rf, ctx) { if (rf & 1) {
|
|
215
|
+
i0.ɵɵelementStart(0, "div", 60);
|
|
216
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_59_div_1_Template, 3, 2, "div", 61)(2, TestSuiteFormComponentExtended_div_59_div_2_Template, 2, 1, "div", 62)(3, TestSuiteFormComponentExtended_div_59_div_3_Template, 7, 0, "div", 63);
|
|
216
217
|
i0.ɵɵelementEnd();
|
|
217
218
|
} if (rf & 2) {
|
|
218
219
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -223,24 +224,24 @@ function TestSuiteFormComponentExtended_div_47_Template(rf, ctx) { if (rf & 1) {
|
|
|
223
224
|
i0.ɵɵadvance();
|
|
224
225
|
i0.ɵɵproperty("ngIf", ctx_r0.testsLoaded && !ctx_r0.loadingTests && ctx_r0.suiteTests.length === 0);
|
|
225
226
|
} }
|
|
226
|
-
function
|
|
227
|
-
i0.ɵɵelementStart(0, "div",
|
|
228
|
-
i0.ɵɵelement(1, "div",
|
|
229
|
-
i0.ɵɵelementStart(2, "div",
|
|
230
|
-
i0.ɵɵelement(3, "div",
|
|
227
|
+
function TestSuiteFormComponentExtended_div_60_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
228
|
+
i0.ɵɵelementStart(0, "div", 67);
|
|
229
|
+
i0.ɵɵelement(1, "div", 69);
|
|
230
|
+
i0.ɵɵelementStart(2, "div", 70);
|
|
231
|
+
i0.ɵɵelement(3, "div", 71)(4, "div", 72);
|
|
231
232
|
i0.ɵɵelementEnd()();
|
|
232
233
|
} }
|
|
233
|
-
function
|
|
234
|
-
i0.ɵɵelementStart(0, "div",
|
|
235
|
-
i0.ɵɵtemplate(2,
|
|
234
|
+
function TestSuiteFormComponentExtended_div_60_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
235
|
+
i0.ɵɵelementStart(0, "div", 64)(1, "div", 65);
|
|
236
|
+
i0.ɵɵtemplate(2, TestSuiteFormComponentExtended_div_60_div_1_div_2_Template, 5, 0, "div", 66);
|
|
236
237
|
i0.ɵɵelementEnd()();
|
|
237
238
|
} if (rf & 2) {
|
|
238
239
|
i0.ɵɵadvance(2);
|
|
239
240
|
i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c2));
|
|
240
241
|
} }
|
|
241
|
-
function
|
|
242
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_span_13_Template(rf, ctx) { if (rf & 1) {
|
|
242
243
|
i0.ɵɵelementStart(0, "span");
|
|
243
|
-
i0.ɵɵelement(1, "i",
|
|
244
|
+
i0.ɵɵelement(1, "i", 103);
|
|
244
245
|
i0.ɵɵtext(2);
|
|
245
246
|
i0.ɵɵelementEnd();
|
|
246
247
|
} if (rf & 2) {
|
|
@@ -249,9 +250,9 @@ function TestSuiteFormComponentExtended_div_48_div_2_div_1_span_13_Template(rf,
|
|
|
249
250
|
i0.ɵɵadvance(2);
|
|
250
251
|
i0.ɵɵtextInterpolate3(" ", run_r6.PassedTests, "/", run_r6.TotalTests, " (", ctx_r0.getPassRate(run_r6).toFixed(0), "%) ");
|
|
251
252
|
} }
|
|
252
|
-
function
|
|
253
|
-
i0.ɵɵelementStart(0, "span",
|
|
254
|
-
i0.ɵɵelement(1, "i",
|
|
253
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_span_15_Template(rf, ctx) { if (rf & 1) {
|
|
254
|
+
i0.ɵɵelementStart(0, "span", 104);
|
|
255
|
+
i0.ɵɵelement(1, "i", 91);
|
|
255
256
|
i0.ɵɵelementEnd();
|
|
256
257
|
} if (rf & 2) {
|
|
257
258
|
const run_r6 = i0.ɵɵnextContext().$implicit;
|
|
@@ -259,16 +260,16 @@ function TestSuiteFormComponentExtended_div_48_div_2_div_1_span_15_Template(rf,
|
|
|
259
260
|
i0.ɵɵadvance();
|
|
260
261
|
i0.ɵɵclassProp("fa-circle-check", run_r6.Status === "Completed")("fa-circle-xmark", run_r6.Status === "Failed")("fa-spinner", run_r6.Status === "Running")("fa-clock", run_r6.Status === "Pending")("fa-ban", run_r6.Status === "Cancelled");
|
|
261
262
|
} }
|
|
262
|
-
function
|
|
263
|
-
i0.ɵɵelementStart(0, "span",
|
|
264
|
-
i0.ɵɵelement(1, "i",
|
|
265
|
-
i0.ɵɵelementStart(2, "span",
|
|
266
|
-
i0.ɵɵelement(3, "i",
|
|
263
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_span_16_Template(rf, ctx) { if (rf & 1) {
|
|
264
|
+
i0.ɵɵelementStart(0, "span", 105);
|
|
265
|
+
i0.ɵɵelement(1, "i", 106);
|
|
266
|
+
i0.ɵɵelementStart(2, "span", 107);
|
|
267
|
+
i0.ɵɵelement(3, "i", 108);
|
|
267
268
|
i0.ɵɵelementEnd()();
|
|
268
269
|
} }
|
|
269
|
-
function
|
|
270
|
-
i0.ɵɵelementStart(0, "span",
|
|
271
|
-
i0.ɵɵelement(1, "i",
|
|
270
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_span_17_Template(rf, ctx) { if (rf & 1) {
|
|
271
|
+
i0.ɵɵelementStart(0, "span", 109);
|
|
272
|
+
i0.ɵɵelement(1, "i", 110);
|
|
272
273
|
i0.ɵɵelementStart(2, "span");
|
|
273
274
|
i0.ɵɵtext(3);
|
|
274
275
|
i0.ɵɵelementEnd()();
|
|
@@ -279,8 +280,8 @@ function TestSuiteFormComponentExtended_div_48_div_2_div_1_span_17_Template(rf,
|
|
|
279
280
|
i0.ɵɵadvance(3);
|
|
280
281
|
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(run_r6).toFixed(0), "%");
|
|
281
282
|
} }
|
|
282
|
-
function
|
|
283
|
-
i0.ɵɵelementStart(0, "span",
|
|
283
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_div_18_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
284
|
+
i0.ɵɵelementStart(0, "span", 113);
|
|
284
285
|
i0.ɵɵtext(1);
|
|
285
286
|
i0.ɵɵelementEnd();
|
|
286
287
|
} if (rf & 2) {
|
|
@@ -288,9 +289,9 @@ function TestSuiteFormComponentExtended_div_48_div_2_div_1_div_18_span_1_Templat
|
|
|
288
289
|
i0.ɵɵadvance();
|
|
289
290
|
i0.ɵɵtextInterpolate(tag_r7);
|
|
290
291
|
} }
|
|
291
|
-
function
|
|
292
|
-
i0.ɵɵelementStart(0, "div",
|
|
293
|
-
i0.ɵɵtemplate(1,
|
|
292
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_div_18_Template(rf, ctx) { if (rf & 1) {
|
|
293
|
+
i0.ɵɵelementStart(0, "div", 111);
|
|
294
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_60_div_2_div_1_div_18_span_1_Template, 2, 1, "span", 112);
|
|
294
295
|
i0.ɵɵelementEnd();
|
|
295
296
|
} if (rf & 2) {
|
|
296
297
|
const run_r6 = i0.ɵɵnextContext().$implicit;
|
|
@@ -298,31 +299,31 @@ function TestSuiteFormComponentExtended_div_48_div_2_div_1_div_18_Template(rf, c
|
|
|
298
299
|
i0.ɵɵadvance();
|
|
299
300
|
i0.ɵɵproperty("ngForOf", ctx_r0.getRunTags(run_r6));
|
|
300
301
|
} }
|
|
301
|
-
function
|
|
302
|
+
function TestSuiteFormComponentExtended_div_60_div_2_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
302
303
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
303
|
-
i0.ɵɵelementStart(0, "div",
|
|
304
|
-
i0.ɵɵlistener("click", function
|
|
305
|
-
i0.ɵɵelementStart(1, "div",
|
|
306
|
-
i0.ɵɵelement(2, "i",
|
|
304
|
+
i0.ɵɵelementStart(0, "div", 89);
|
|
305
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_60_div_2_div_1_Template_div_click_0_listener() { const run_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r6.ID)); });
|
|
306
|
+
i0.ɵɵelementStart(1, "div", 90);
|
|
307
|
+
i0.ɵɵelement(2, "i", 91);
|
|
307
308
|
i0.ɵɵelementEnd();
|
|
308
|
-
i0.ɵɵelementStart(3, "div",
|
|
309
|
+
i0.ɵɵelementStart(3, "div", 92)(4, "div", 93)(5, "span", 94);
|
|
309
310
|
i0.ɵɵtext(6);
|
|
310
311
|
i0.ɵɵelementEnd();
|
|
311
|
-
i0.ɵɵelementStart(7, "span",
|
|
312
|
+
i0.ɵɵelementStart(7, "span", 95);
|
|
312
313
|
i0.ɵɵtext(8);
|
|
313
314
|
i0.ɵɵelementEnd()();
|
|
314
|
-
i0.ɵɵelementStart(9, "div",
|
|
315
|
-
i0.ɵɵelement(11, "i",
|
|
315
|
+
i0.ɵɵelementStart(9, "div", 96)(10, "span");
|
|
316
|
+
i0.ɵɵelement(11, "i", 97);
|
|
316
317
|
i0.ɵɵtext(12);
|
|
317
318
|
i0.ɵɵelementEnd();
|
|
318
|
-
i0.ɵɵtemplate(13,
|
|
319
|
+
i0.ɵɵtemplate(13, TestSuiteFormComponentExtended_div_60_div_2_div_1_span_13_Template, 3, 3, "span", 81);
|
|
319
320
|
i0.ɵɵelementEnd();
|
|
320
|
-
i0.ɵɵelementStart(14, "div",
|
|
321
|
-
i0.ɵɵtemplate(15,
|
|
321
|
+
i0.ɵɵelementStart(14, "div", 98);
|
|
322
|
+
i0.ɵɵtemplate(15, TestSuiteFormComponentExtended_div_60_div_2_div_1_span_15_Template, 2, 12, "span", 99)(16, TestSuiteFormComponentExtended_div_60_div_2_div_1_span_16_Template, 4, 0, "span", 100)(17, TestSuiteFormComponentExtended_div_60_div_2_div_1_span_17_Template, 4, 7, "span", 101);
|
|
322
323
|
i0.ɵɵelementEnd();
|
|
323
|
-
i0.ɵɵtemplate(18,
|
|
324
|
+
i0.ɵɵtemplate(18, TestSuiteFormComponentExtended_div_60_div_2_div_1_div_18_Template, 2, 1, "div", 102);
|
|
324
325
|
i0.ɵɵelementEnd();
|
|
325
|
-
i0.ɵɵelement(19, "i",
|
|
326
|
+
i0.ɵɵelement(19, "i", 82);
|
|
326
327
|
i0.ɵɵelementEnd();
|
|
327
328
|
} if (rf & 2) {
|
|
328
329
|
const run_r6 = ctx.$implicit;
|
|
@@ -350,19 +351,19 @@ function TestSuiteFormComponentExtended_div_48_div_2_div_1_Template(rf, ctx) { i
|
|
|
350
351
|
i0.ɵɵadvance();
|
|
351
352
|
i0.ɵɵproperty("ngIf", ctx_r0.getRunTags(run_r6).length > 0);
|
|
352
353
|
} }
|
|
353
|
-
function
|
|
354
|
-
i0.ɵɵelementStart(0, "div",
|
|
355
|
-
i0.ɵɵtemplate(1,
|
|
354
|
+
function TestSuiteFormComponentExtended_div_60_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
355
|
+
i0.ɵɵelementStart(0, "div", 87);
|
|
356
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_60_div_2_div_1_Template, 20, 22, "div", 88);
|
|
356
357
|
i0.ɵɵelementEnd();
|
|
357
358
|
} if (rf & 2) {
|
|
358
359
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
359
360
|
i0.ɵɵadvance();
|
|
360
361
|
i0.ɵɵproperty("ngForOf", ctx_r0.suiteRuns);
|
|
361
362
|
} }
|
|
362
|
-
function
|
|
363
|
+
function TestSuiteFormComponentExtended_div_60_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
363
364
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
364
|
-
i0.ɵɵelementStart(0, "div",
|
|
365
|
-
i0.ɵɵelement(2, "i",
|
|
365
|
+
i0.ɵɵelementStart(0, "div", 83)(1, "div", 84);
|
|
366
|
+
i0.ɵɵelement(2, "i", 114);
|
|
366
367
|
i0.ɵɵelementEnd();
|
|
367
368
|
i0.ɵɵelementStart(3, "h4");
|
|
368
369
|
i0.ɵɵtext(4, "No Suite Runs Yet");
|
|
@@ -370,15 +371,15 @@ function TestSuiteFormComponentExtended_div_48_div_3_Template(rf, ctx) { if (rf
|
|
|
370
371
|
i0.ɵɵelementStart(5, "p");
|
|
371
372
|
i0.ɵɵtext(6, "Run this suite to see execution history and results here.");
|
|
372
373
|
i0.ɵɵelementEnd();
|
|
373
|
-
i0.ɵɵelementStart(7, "button",
|
|
374
|
-
i0.ɵɵlistener("click", function
|
|
375
|
-
i0.ɵɵelement(8, "i",
|
|
374
|
+
i0.ɵɵelementStart(7, "button", 21);
|
|
375
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_60_div_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
|
|
376
|
+
i0.ɵɵelement(8, "i", 22);
|
|
376
377
|
i0.ɵɵtext(9, " Run Suite Now ");
|
|
377
378
|
i0.ɵɵelementEnd()();
|
|
378
379
|
} }
|
|
379
|
-
function
|
|
380
|
-
i0.ɵɵelementStart(0, "div",
|
|
381
|
-
i0.ɵɵtemplate(1,
|
|
380
|
+
function TestSuiteFormComponentExtended_div_60_Template(rf, ctx) { if (rf & 1) {
|
|
381
|
+
i0.ɵɵelementStart(0, "div", 85);
|
|
382
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_60_div_1_Template, 3, 2, "div", 61)(2, TestSuiteFormComponentExtended_div_60_div_2_Template, 2, 1, "div", 86)(3, TestSuiteFormComponentExtended_div_60_div_3_Template, 10, 0, "div", 63);
|
|
382
383
|
i0.ɵɵelementEnd();
|
|
383
384
|
} if (rf & 2) {
|
|
384
385
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -389,12 +390,12 @@ function TestSuiteFormComponentExtended_div_48_Template(rf, ctx) { if (rf & 1) {
|
|
|
389
390
|
i0.ɵɵadvance();
|
|
390
391
|
i0.ɵɵproperty("ngIf", ctx_r0.runsLoaded && !ctx_r0.loadingRuns && ctx_r0.suiteRuns.length === 0);
|
|
391
392
|
} }
|
|
392
|
-
function
|
|
393
|
-
i0.ɵɵelementStart(0, "div",
|
|
394
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
393
|
+
function TestSuiteFormComponentExtended_div_61_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
394
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
395
|
+
i0.ɵɵelement(1, "mj-loading", 116);
|
|
395
396
|
i0.ɵɵelementEnd();
|
|
396
397
|
} }
|
|
397
|
-
function
|
|
398
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_span_20_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
398
399
|
i0.ɵɵelementStart(0, "span");
|
|
399
400
|
i0.ɵɵtext(1);
|
|
400
401
|
i0.ɵɵelementEnd();
|
|
@@ -403,10 +404,10 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_span_20_span_2_Tem
|
|
|
403
404
|
i0.ɵɵadvance();
|
|
404
405
|
i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r0.selectedTags.length, " tags");
|
|
405
406
|
} }
|
|
406
|
-
function
|
|
407
|
-
i0.ɵɵelementStart(0, "span",
|
|
407
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_span_20_Template(rf, ctx) { if (rf & 1) {
|
|
408
|
+
i0.ɵɵelementStart(0, "span", 129);
|
|
408
409
|
i0.ɵɵtext(1);
|
|
409
|
-
i0.ɵɵtemplate(2,
|
|
410
|
+
i0.ɵɵtemplate(2, TestSuiteFormComponentExtended_div_61_ng_container_2_span_20_span_2_Template, 2, 1, "span", 81);
|
|
410
411
|
i0.ɵɵelementEnd();
|
|
411
412
|
} if (rf & 2) {
|
|
412
413
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -415,8 +416,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_span_20_Template(r
|
|
|
415
416
|
i0.ɵɵadvance();
|
|
416
417
|
i0.ɵɵproperty("ngIf", ctx_r0.selectedTags.length > 0);
|
|
417
418
|
} }
|
|
418
|
-
function
|
|
419
|
-
i0.ɵɵelementStart(0, "span",
|
|
419
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_span_3_Template(rf, ctx) { if (rf & 1) {
|
|
420
|
+
i0.ɵɵelementStart(0, "span", 139);
|
|
420
421
|
i0.ɵɵtext(1);
|
|
421
422
|
i0.ɵɵelementEnd();
|
|
422
423
|
} if (rf & 2) {
|
|
@@ -424,14 +425,14 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_div_22_div_13_span
|
|
|
424
425
|
i0.ɵɵadvance();
|
|
425
426
|
i0.ɵɵtextInterpolate1("(", ctx_r0.selectedTags.length, " selected)");
|
|
426
427
|
} }
|
|
427
|
-
function
|
|
428
|
-
i0.ɵɵelement(0, "i",
|
|
428
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_button_8_i_1_Template(rf, ctx) { if (rf & 1) {
|
|
429
|
+
i0.ɵɵelement(0, "i", 142);
|
|
429
430
|
} }
|
|
430
|
-
function
|
|
431
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_button_8_Template(rf, ctx) { if (rf & 1) {
|
|
431
432
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
432
|
-
i0.ɵɵelementStart(0, "button",
|
|
433
|
-
i0.ɵɵlistener("click", function
|
|
434
|
-
i0.ɵɵtemplate(1,
|
|
433
|
+
i0.ɵɵelementStart(0, "button", 140);
|
|
434
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_button_8_Template_button_click_0_listener() { const tag_r13 = i0.ɵɵrestoreView(_r12).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(tag_r13)); });
|
|
435
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_button_8_i_1_Template, 1, 0, "i", 141);
|
|
435
436
|
i0.ɵɵtext(2);
|
|
436
437
|
i0.ɵɵelementEnd();
|
|
437
438
|
} if (rf & 2) {
|
|
@@ -443,18 +444,18 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_div_22_div_13_butt
|
|
|
443
444
|
i0.ɵɵadvance();
|
|
444
445
|
i0.ɵɵtextInterpolate1(" ", tag_r13, " ");
|
|
445
446
|
} }
|
|
446
|
-
function
|
|
447
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_Template(rf, ctx) { if (rf & 1) {
|
|
447
448
|
const _r11 = i0.ɵɵgetCurrentView();
|
|
448
|
-
i0.ɵɵelementStart(0, "div",
|
|
449
|
+
i0.ɵɵelementStart(0, "div", 131)(1, "label");
|
|
449
450
|
i0.ɵɵtext(2, "Filter by Tag ");
|
|
450
|
-
i0.ɵɵtemplate(3,
|
|
451
|
+
i0.ɵɵtemplate(3, TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_span_3_Template, 2, 1, "span", 135);
|
|
451
452
|
i0.ɵɵelementEnd();
|
|
452
|
-
i0.ɵɵelementStart(4, "div",
|
|
453
|
-
i0.ɵɵlistener("click", function
|
|
454
|
-
i0.ɵɵelement(6, "i",
|
|
453
|
+
i0.ɵɵelementStart(4, "div", 136)(5, "button", 137);
|
|
454
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r11); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleTagFilter(null)); });
|
|
455
|
+
i0.ɵɵelement(6, "i", 9);
|
|
455
456
|
i0.ɵɵtext(7, " All Tags ");
|
|
456
457
|
i0.ɵɵelementEnd();
|
|
457
|
-
i0.ɵɵtemplate(8,
|
|
458
|
+
i0.ɵɵtemplate(8, TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_button_8_Template, 3, 4, "button", 138);
|
|
458
459
|
i0.ɵɵelementEnd()();
|
|
459
460
|
} if (rf & 2) {
|
|
460
461
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
@@ -465,28 +466,28 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_div_22_div_13_Temp
|
|
|
465
466
|
i0.ɵɵadvance(3);
|
|
466
467
|
i0.ɵɵproperty("ngForOf", ctx_r0.uniqueTags);
|
|
467
468
|
} }
|
|
468
|
-
function
|
|
469
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_Template(rf, ctx) { if (rf & 1) {
|
|
469
470
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
470
|
-
i0.ɵɵelementStart(0, "div",
|
|
471
|
+
i0.ɵɵelementStart(0, "div", 130)(1, "div", 131)(2, "label");
|
|
471
472
|
i0.ɵɵtext(3, "Time Range");
|
|
472
473
|
i0.ɵɵelementEnd();
|
|
473
|
-
i0.ɵɵelementStart(4, "div",
|
|
474
|
-
i0.ɵɵlistener("click", function
|
|
474
|
+
i0.ɵɵelementStart(4, "div", 132)(5, "button", 133);
|
|
475
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("7d")); });
|
|
475
476
|
i0.ɵɵtext(6, "7 Days");
|
|
476
477
|
i0.ɵɵelementEnd();
|
|
477
|
-
i0.ɵɵelementStart(7, "button",
|
|
478
|
-
i0.ɵɵlistener("click", function
|
|
478
|
+
i0.ɵɵelementStart(7, "button", 133);
|
|
479
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("30d")); });
|
|
479
480
|
i0.ɵɵtext(8, "30 Days");
|
|
480
481
|
i0.ɵɵelementEnd();
|
|
481
|
-
i0.ɵɵelementStart(9, "button",
|
|
482
|
-
i0.ɵɵlistener("click", function
|
|
482
|
+
i0.ɵɵelementStart(9, "button", 133);
|
|
483
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("90d")); });
|
|
483
484
|
i0.ɵɵtext(10, "90 Days");
|
|
484
485
|
i0.ɵɵelementEnd();
|
|
485
|
-
i0.ɵɵelementStart(11, "button",
|
|
486
|
-
i0.ɵɵlistener("click", function
|
|
486
|
+
i0.ɵɵelementStart(11, "button", 133);
|
|
487
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r10); const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.setTimeRange("all")); });
|
|
487
488
|
i0.ɵɵtext(12, "All Time");
|
|
488
489
|
i0.ɵɵelementEnd()()();
|
|
489
|
-
i0.ɵɵtemplate(13,
|
|
490
|
+
i0.ɵɵtemplate(13, TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_div_13_Template, 9, 4, "div", 134);
|
|
490
491
|
i0.ɵɵelementEnd();
|
|
491
492
|
} if (rf & 2) {
|
|
492
493
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -501,8 +502,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_div_22_Template(rf
|
|
|
501
502
|
i0.ɵɵadvance(2);
|
|
502
503
|
i0.ɵɵproperty("ngIf", ctx_r0.uniqueTags.length > 0);
|
|
503
504
|
} }
|
|
504
|
-
function
|
|
505
|
-
i0.ɵɵelementStart(0, "span",
|
|
505
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_span_20_Template(rf, ctx) { if (rf & 1) {
|
|
506
|
+
i0.ɵɵelementStart(0, "span", 167);
|
|
506
507
|
i0.ɵɵtext(1);
|
|
507
508
|
i0.ɵɵelementEnd();
|
|
508
509
|
} if (rf & 2) {
|
|
@@ -510,8 +511,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_23_tr
|
|
|
510
511
|
i0.ɵɵadvance();
|
|
511
512
|
i0.ɵɵtextInterpolate(tag_r16);
|
|
512
513
|
} }
|
|
513
|
-
function
|
|
514
|
-
i0.ɵɵelementStart(0, "span",
|
|
514
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_span_21_Template(rf, ctx) { if (rf & 1) {
|
|
515
|
+
i0.ɵɵelementStart(0, "span", 168);
|
|
515
516
|
i0.ɵɵtext(1);
|
|
516
517
|
i0.ɵɵelementEnd();
|
|
517
518
|
} if (rf & 2) {
|
|
@@ -519,19 +520,19 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_23_tr
|
|
|
519
520
|
i0.ɵɵadvance();
|
|
520
521
|
i0.ɵɵtextInterpolate1("+", dp_r15.tags.length - 2, "");
|
|
521
522
|
} }
|
|
522
|
-
function
|
|
523
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_Template(rf, ctx) { if (rf & 1) {
|
|
523
524
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
524
|
-
i0.ɵɵelementStart(0, "tr",
|
|
525
|
-
i0.ɵɵlistener("click", function
|
|
525
|
+
i0.ɵɵelementStart(0, "tr", 160);
|
|
526
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_Template_tr_click_0_listener() { const dp_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.openSuiteRun(dp_r15.runId)); });
|
|
526
527
|
i0.ɵɵelementStart(1, "td");
|
|
527
528
|
i0.ɵɵtext(2);
|
|
528
529
|
i0.ɵɵpipe(3, "date");
|
|
529
530
|
i0.ɵɵelementEnd();
|
|
530
|
-
i0.ɵɵelementStart(4, "td")(5, "span",
|
|
531
|
+
i0.ɵɵelementStart(4, "td")(5, "span", 161);
|
|
531
532
|
i0.ɵɵtext(6);
|
|
532
533
|
i0.ɵɵelementEnd()();
|
|
533
|
-
i0.ɵɵelementStart(7, "td")(8, "div",
|
|
534
|
-
i0.ɵɵelement(9, "div",
|
|
534
|
+
i0.ɵɵelementStart(7, "td")(8, "div", 162);
|
|
535
|
+
i0.ɵɵelement(9, "div", 163);
|
|
535
536
|
i0.ɵɵelementStart(10, "span");
|
|
536
537
|
i0.ɵɵtext(11);
|
|
537
538
|
i0.ɵɵelementEnd()()();
|
|
@@ -544,8 +545,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_23_tr
|
|
|
544
545
|
i0.ɵɵelementStart(16, "td");
|
|
545
546
|
i0.ɵɵtext(17);
|
|
546
547
|
i0.ɵɵelementEnd();
|
|
547
|
-
i0.ɵɵelementStart(18, "td")(19, "div",
|
|
548
|
-
i0.ɵɵtemplate(20,
|
|
548
|
+
i0.ɵɵelementStart(18, "td")(19, "div", 164);
|
|
549
|
+
i0.ɵɵtemplate(20, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_span_20_Template, 2, 1, "span", 165)(21, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_span_21_Template, 2, 1, "span", 166);
|
|
549
550
|
i0.ɵɵelementEnd()()();
|
|
550
551
|
} if (rf & 2) {
|
|
551
552
|
const dp_r15 = ctx.$implicit;
|
|
@@ -572,58 +573,58 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_23_tr
|
|
|
572
573
|
i0.ɵɵadvance();
|
|
573
574
|
i0.ɵɵproperty("ngIf", dp_r15.tags.length > 2);
|
|
574
575
|
} }
|
|
575
|
-
function
|
|
576
|
-
i0.ɵɵelementStart(0, "div",
|
|
576
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_div_61_Template(rf, ctx) { if (rf & 1) {
|
|
577
|
+
i0.ɵɵelementStart(0, "div", 169)(1, "p");
|
|
577
578
|
i0.ɵɵtext(2, "No runs match the current filters.");
|
|
578
579
|
i0.ɵɵelementEnd()();
|
|
579
580
|
} }
|
|
580
|
-
function
|
|
581
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_Template(rf, ctx) { if (rf & 1) {
|
|
581
582
|
i0.ɵɵelementContainerStart(0);
|
|
582
|
-
i0.ɵɵelementStart(1, "div",
|
|
583
|
-
i0.ɵɵelement(4, "i",
|
|
583
|
+
i0.ɵɵelementStart(1, "div", 143)(2, "div", 144)(3, "div", 145);
|
|
584
|
+
i0.ɵɵelement(4, "i", 114);
|
|
584
585
|
i0.ɵɵelementEnd();
|
|
585
|
-
i0.ɵɵelementStart(5, "div",
|
|
586
|
+
i0.ɵɵelementStart(5, "div", 146)(6, "div", 147);
|
|
586
587
|
i0.ɵɵtext(7);
|
|
587
588
|
i0.ɵɵelementEnd();
|
|
588
|
-
i0.ɵɵelementStart(8, "div",
|
|
589
|
+
i0.ɵɵelementStart(8, "div", 148);
|
|
589
590
|
i0.ɵɵtext(9, "Total Runs");
|
|
590
591
|
i0.ɵɵelementEnd()()();
|
|
591
|
-
i0.ɵɵelementStart(10, "div",
|
|
592
|
-
i0.ɵɵelement(12, "i",
|
|
592
|
+
i0.ɵɵelementStart(10, "div", 144)(11, "div", 149);
|
|
593
|
+
i0.ɵɵelement(12, "i", 103);
|
|
593
594
|
i0.ɵɵelementEnd();
|
|
594
|
-
i0.ɵɵelementStart(13, "div",
|
|
595
|
+
i0.ɵɵelementStart(13, "div", 146)(14, "div", 147);
|
|
595
596
|
i0.ɵɵtext(15);
|
|
596
597
|
i0.ɵɵelementEnd();
|
|
597
|
-
i0.ɵɵelementStart(16, "div",
|
|
598
|
+
i0.ɵɵelementStart(16, "div", 148);
|
|
598
599
|
i0.ɵɵtext(17, "Avg Pass Rate");
|
|
599
600
|
i0.ɵɵelementEnd();
|
|
600
|
-
i0.ɵɵelementStart(18, "div",
|
|
601
|
-
i0.ɵɵelement(19, "i",
|
|
601
|
+
i0.ɵɵelementStart(18, "div", 150);
|
|
602
|
+
i0.ɵɵelement(19, "i", 16);
|
|
602
603
|
i0.ɵɵtext(20);
|
|
603
604
|
i0.ɵɵelementEnd()()();
|
|
604
|
-
i0.ɵɵelementStart(21, "div",
|
|
605
|
-
i0.ɵɵelement(23, "i",
|
|
605
|
+
i0.ɵɵelementStart(21, "div", 144)(22, "div", 151);
|
|
606
|
+
i0.ɵɵelement(23, "i", 108);
|
|
606
607
|
i0.ɵɵelementEnd();
|
|
607
|
-
i0.ɵɵelementStart(24, "div",
|
|
608
|
+
i0.ɵɵelementStart(24, "div", 146)(25, "div", 147);
|
|
608
609
|
i0.ɵɵtext(26);
|
|
609
610
|
i0.ɵɵelementEnd();
|
|
610
|
-
i0.ɵɵelementStart(27, "div",
|
|
611
|
+
i0.ɵɵelementStart(27, "div", 148);
|
|
611
612
|
i0.ɵɵtext(28, "Avg Duration");
|
|
612
613
|
i0.ɵɵelementEnd()()();
|
|
613
|
-
i0.ɵɵelementStart(29, "div",
|
|
614
|
-
i0.ɵɵelement(31, "i",
|
|
614
|
+
i0.ɵɵelementStart(29, "div", 144)(30, "div", 152);
|
|
615
|
+
i0.ɵɵelement(31, "i", 153);
|
|
615
616
|
i0.ɵɵelementEnd();
|
|
616
|
-
i0.ɵɵelementStart(32, "div",
|
|
617
|
+
i0.ɵɵelementStart(32, "div", 146)(33, "div", 147);
|
|
617
618
|
i0.ɵɵtext(34);
|
|
618
619
|
i0.ɵɵelementEnd();
|
|
619
|
-
i0.ɵɵelementStart(35, "div",
|
|
620
|
+
i0.ɵɵelementStart(35, "div", 148);
|
|
620
621
|
i0.ɵɵtext(36, "Total Cost");
|
|
621
622
|
i0.ɵɵelementEnd()()()();
|
|
622
|
-
i0.ɵɵelementStart(37, "div",
|
|
623
|
-
i0.ɵɵelement(39, "i",
|
|
623
|
+
i0.ɵɵelementStart(37, "div", 154)(38, "h3");
|
|
624
|
+
i0.ɵɵelement(39, "i", 155);
|
|
624
625
|
i0.ɵɵtext(40, " Run History");
|
|
625
626
|
i0.ɵɵelementEnd();
|
|
626
|
-
i0.ɵɵelementStart(41, "div",
|
|
627
|
+
i0.ɵɵelementStart(41, "div", 156)(42, "table", 157)(43, "thead")(44, "tr")(45, "th");
|
|
627
628
|
i0.ɵɵtext(46, "Date");
|
|
628
629
|
i0.ɵɵelementEnd();
|
|
629
630
|
i0.ɵɵelementStart(47, "th");
|
|
@@ -645,9 +646,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_23_Te
|
|
|
645
646
|
i0.ɵɵtext(58, "Tags");
|
|
646
647
|
i0.ɵɵelementEnd()()();
|
|
647
648
|
i0.ɵɵelementStart(59, "tbody");
|
|
648
|
-
i0.ɵɵtemplate(60,
|
|
649
|
+
i0.ɵɵtemplate(60, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_tr_60_Template, 22, 20, "tr", 158);
|
|
649
650
|
i0.ɵɵelementEnd()()();
|
|
650
|
-
i0.ɵɵtemplate(61,
|
|
651
|
+
i0.ɵɵtemplate(61, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_div_61_Template, 3, 0, "div", 159);
|
|
651
652
|
i0.ɵɵelementEnd();
|
|
652
653
|
i0.ɵɵelementContainerEnd();
|
|
653
654
|
} if (rf & 2) {
|
|
@@ -671,20 +672,20 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_23_Te
|
|
|
671
672
|
i0.ɵɵadvance();
|
|
672
673
|
i0.ɵɵproperty("ngIf", ctx_r0.getFilteredAnalyticsData().length === 0);
|
|
673
674
|
} }
|
|
674
|
-
function
|
|
675
|
-
i0.ɵɵelementStart(0, "div",
|
|
676
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
675
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
676
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
677
|
+
i0.ɵɵelement(1, "mj-loading", 171);
|
|
677
678
|
i0.ɵɵelementEnd();
|
|
678
679
|
} }
|
|
679
|
-
function
|
|
680
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_button_9_Template(rf, ctx) { if (rf & 1) {
|
|
680
681
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
681
|
-
i0.ɵɵelementStart(0, "button",
|
|
682
|
-
i0.ɵɵlistener("click", function
|
|
683
|
-
i0.ɵɵelement(1, "i",
|
|
682
|
+
i0.ɵɵelementStart(0, "button", 194);
|
|
683
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_button_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.clearMatrixFilter()); });
|
|
684
|
+
i0.ɵɵelement(1, "i", 195);
|
|
684
685
|
i0.ɵɵelementEnd();
|
|
685
686
|
} }
|
|
686
|
-
function
|
|
687
|
-
i0.ɵɵelementStart(0, "span",
|
|
687
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_div_3_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
688
|
+
i0.ɵɵelementStart(0, "span", 204);
|
|
688
689
|
i0.ɵɵtext(1);
|
|
689
690
|
i0.ɵɵelementEnd();
|
|
690
691
|
} if (rf & 2) {
|
|
@@ -692,8 +693,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
692
693
|
i0.ɵɵadvance();
|
|
693
694
|
i0.ɵɵtextInterpolate(tag_r21);
|
|
694
695
|
} }
|
|
695
|
-
function
|
|
696
|
-
i0.ɵɵelementStart(0, "span",
|
|
696
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_div_3_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
697
|
+
i0.ɵɵelementStart(0, "span", 205);
|
|
697
698
|
i0.ɵɵtext(1);
|
|
698
699
|
i0.ɵɵelementEnd();
|
|
699
700
|
} if (rf & 2) {
|
|
@@ -701,9 +702,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
701
702
|
i0.ɵɵadvance();
|
|
702
703
|
i0.ɵɵtextInterpolate1("+", run_r20.tags.length - 2, "");
|
|
703
704
|
} }
|
|
704
|
-
function
|
|
705
|
-
i0.ɵɵelementStart(0, "div",
|
|
706
|
-
i0.ɵɵtemplate(1,
|
|
705
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
706
|
+
i0.ɵɵelementStart(0, "div", 201);
|
|
707
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_div_3_span_1_Template, 2, 1, "span", 202)(2, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_div_3_span_2_Template, 2, 1, "span", 203);
|
|
707
708
|
i0.ɵɵelementEnd();
|
|
708
709
|
} if (rf & 2) {
|
|
709
710
|
const run_r20 = i0.ɵɵnextContext().$implicit;
|
|
@@ -712,17 +713,17 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
712
713
|
i0.ɵɵadvance();
|
|
713
714
|
i0.ɵɵproperty("ngIf", run_r20.tags.length > 2);
|
|
714
715
|
} }
|
|
715
|
-
function
|
|
716
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_Template(rf, ctx) { if (rf & 1) {
|
|
716
717
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
717
|
-
i0.ɵɵelementStart(0, "th",
|
|
718
|
+
i0.ɵɵelementStart(0, "th", 196);
|
|
718
719
|
i0.ɵɵpipe(1, "date");
|
|
719
|
-
i0.ɵɵlistener("click", function
|
|
720
|
-
i0.ɵɵelementStart(2, "div",
|
|
721
|
-
i0.ɵɵtemplate(3,
|
|
722
|
-
i0.ɵɵelementStart(4, "div",
|
|
720
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_Template_th_click_0_listener() { const run_r20 = i0.ɵɵrestoreView(_r19).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.openSuiteRun(run_r20.runId)); });
|
|
721
|
+
i0.ɵɵelementStart(2, "div", 197);
|
|
722
|
+
i0.ɵɵtemplate(3, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_div_3_Template, 3, 2, "div", 198);
|
|
723
|
+
i0.ɵɵelementStart(4, "div", 199);
|
|
723
724
|
i0.ɵɵtext(5);
|
|
724
725
|
i0.ɵɵelementEnd();
|
|
725
|
-
i0.ɵɵelementStart(6, "div",
|
|
726
|
+
i0.ɵɵelementStart(6, "div", 200);
|
|
726
727
|
i0.ɵɵtext(7);
|
|
727
728
|
i0.ɵɵelementEnd()()();
|
|
728
729
|
} if (rf & 2) {
|
|
@@ -738,9 +739,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
738
739
|
i0.ɵɵadvance();
|
|
739
740
|
i0.ɵɵtextInterpolate1(" ", run_r20.passRate.toFixed(0), "% ");
|
|
740
741
|
} }
|
|
741
|
-
function
|
|
742
|
-
i0.ɵɵelementStart(0, "span",
|
|
743
|
-
i0.ɵɵelement(1, "i",
|
|
742
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
743
|
+
i0.ɵɵelementStart(0, "span", 219);
|
|
744
|
+
i0.ɵɵelement(1, "i", 91);
|
|
744
745
|
i0.ɵɵelementEnd();
|
|
745
746
|
} if (rf & 2) {
|
|
746
747
|
const result_r26 = i0.ɵɵnextContext().ngIf;
|
|
@@ -750,15 +751,15 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
750
751
|
i0.ɵɵadvance();
|
|
751
752
|
i0.ɵɵclassProp("fa-check", result_r26.status === "Passed")("fa-times", result_r26.status === "Failed")("fa-exclamation", result_r26.status === "Error")("fa-hourglass-end", result_r26.status === "Timeout")("fa-forward", result_r26.status === "Skipped")("fa-spinner", result_r26.status === "Running")("fa-clock", result_r26.status === "Pending");
|
|
752
753
|
} }
|
|
753
|
-
function
|
|
754
|
-
i0.ɵɵelementStart(0, "span",
|
|
755
|
-
i0.ɵɵelement(1, "i",
|
|
754
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_3_Template(rf, ctx) { if (rf & 1) {
|
|
755
|
+
i0.ɵɵelementStart(0, "span", 220);
|
|
756
|
+
i0.ɵɵelement(1, "i", 221);
|
|
756
757
|
i0.ɵɵelementEnd();
|
|
757
758
|
} }
|
|
758
|
-
function
|
|
759
|
-
i0.ɵɵelementStart(0, "span",
|
|
760
|
-
i0.ɵɵelement(1, "i",
|
|
761
|
-
i0.ɵɵelementStart(2, "span",
|
|
759
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_4_Template(rf, ctx) { if (rf & 1) {
|
|
760
|
+
i0.ɵɵelementStart(0, "span", 222);
|
|
761
|
+
i0.ɵɵelement(1, "i", 106);
|
|
762
|
+
i0.ɵɵelementStart(2, "span", 223);
|
|
762
763
|
i0.ɵɵtext(3);
|
|
763
764
|
i0.ɵɵelementEnd()();
|
|
764
765
|
} if (rf & 2) {
|
|
@@ -769,10 +770,10 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
769
770
|
i0.ɵɵadvance(3);
|
|
770
771
|
i0.ɵɵtextInterpolate(result_r26.humanRating);
|
|
771
772
|
} }
|
|
772
|
-
function
|
|
773
|
-
i0.ɵɵelementStart(0, "span",
|
|
774
|
-
i0.ɵɵelement(1, "i",
|
|
775
|
-
i0.ɵɵelementStart(2, "span",
|
|
773
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_5_Template(rf, ctx) { if (rf & 1) {
|
|
774
|
+
i0.ɵɵelementStart(0, "span", 224);
|
|
775
|
+
i0.ɵɵelement(1, "i", 110);
|
|
776
|
+
i0.ɵɵelementStart(2, "span", 225);
|
|
776
777
|
i0.ɵɵtext(3);
|
|
777
778
|
i0.ɵɵelementEnd()();
|
|
778
779
|
} if (rf & 2) {
|
|
@@ -782,15 +783,15 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
782
783
|
i0.ɵɵadvance(3);
|
|
783
784
|
i0.ɵɵtextInterpolate((result_r26.score * 100).toFixed(0));
|
|
784
785
|
} }
|
|
785
|
-
function
|
|
786
|
-
i0.ɵɵelementStart(0, "span",
|
|
787
|
-
i0.ɵɵelement(1, "i",
|
|
786
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_6_Template(rf, ctx) { if (rf & 1) {
|
|
787
|
+
i0.ɵɵelementStart(0, "span", 226);
|
|
788
|
+
i0.ɵɵelement(1, "i", 110);
|
|
788
789
|
i0.ɵɵelementEnd();
|
|
789
790
|
} }
|
|
790
|
-
function
|
|
791
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_Template(rf, ctx) { if (rf & 1) {
|
|
791
792
|
i0.ɵɵelementContainerStart(0);
|
|
792
|
-
i0.ɵɵelementStart(1, "div",
|
|
793
|
-
i0.ɵɵtemplate(2,
|
|
793
|
+
i0.ɵɵelementStart(1, "div", 213);
|
|
794
|
+
i0.ɵɵtemplate(2, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_2_Template, 2, 18, "span", 214)(3, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_3_Template, 2, 0, "span", 215)(4, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_4_Template, 4, 10, "span", 216)(5, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_5_Template, 4, 10, "span", 217)(6, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_span_6_Template, 2, 0, "span", 218);
|
|
794
795
|
i0.ɵɵelementEnd();
|
|
795
796
|
i0.ɵɵelementContainerEnd();
|
|
796
797
|
} if (rf & 2) {
|
|
@@ -807,16 +808,16 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
807
808
|
i0.ɵɵadvance();
|
|
808
809
|
i0.ɵɵproperty("ngIf", ctx_r0.evalPreferences.showAuto && result_r26.score == null);
|
|
809
810
|
} }
|
|
810
|
-
function
|
|
811
|
-
i0.ɵɵelementStart(0, "span",
|
|
812
|
-
i0.ɵɵelement(1, "i",
|
|
811
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
812
|
+
i0.ɵɵelementStart(0, "span", 227);
|
|
813
|
+
i0.ɵɵelement(1, "i", 228);
|
|
813
814
|
i0.ɵɵelementEnd();
|
|
814
815
|
} }
|
|
815
|
-
function
|
|
816
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_Template(rf, ctx) { if (rf & 1) {
|
|
816
817
|
const _r24 = i0.ɵɵgetCurrentView();
|
|
817
|
-
i0.ɵɵelementStart(0, "td",
|
|
818
|
-
i0.ɵɵlistener("click", function
|
|
819
|
-
i0.ɵɵtemplate(1,
|
|
818
|
+
i0.ɵɵelementStart(0, "td", 211);
|
|
819
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_Template_td_click_0_listener($event) { const run_r25 = i0.ɵɵrestoreView(_r24).$implicit; const test_r23 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.onMatrixCellClick(ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId), $event)); });
|
|
820
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_ng_container_1_Template, 7, 5, "ng-container", 81)(2, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_span_2_Template, 2, 0, "span", 212);
|
|
820
821
|
i0.ɵɵelementEnd();
|
|
821
822
|
} if (rf & 2) {
|
|
822
823
|
let tmp_11_0;
|
|
@@ -830,18 +831,18 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
830
831
|
i0.ɵɵadvance();
|
|
831
832
|
i0.ɵɵproperty("ngIf", !ctx_r0.getTestResultForRun(run_r25.runId, test_r23.testId));
|
|
832
833
|
} }
|
|
833
|
-
function
|
|
834
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_Template(rf, ctx) { if (rf & 1) {
|
|
834
835
|
const _r22 = i0.ɵɵgetCurrentView();
|
|
835
|
-
i0.ɵɵelementStart(0, "tr",
|
|
836
|
-
i0.ɵɵlistener("click", function
|
|
837
|
-
i0.ɵɵelementStart(1, "td",
|
|
836
|
+
i0.ɵɵelementStart(0, "tr", 206);
|
|
837
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_Template_tr_click_0_listener() { const test_r23 = i0.ɵɵrestoreView(_r22).$implicit; const ctx_r0 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r0.selectMatrixRow(test_r23.testId)); });
|
|
838
|
+
i0.ɵɵelementStart(1, "td", 207);
|
|
838
839
|
i0.ɵɵtext(2);
|
|
839
840
|
i0.ɵɵelementEnd();
|
|
840
|
-
i0.ɵɵelementStart(3, "td",
|
|
841
|
+
i0.ɵɵelementStart(3, "td", 208)(4, "span", 209);
|
|
841
842
|
i0.ɵɵtext(5);
|
|
842
843
|
i0.ɵɵelementEnd()();
|
|
843
|
-
i0.ɵɵtemplate(6,
|
|
844
|
-
i0.ɵɵelement(7, "td",
|
|
844
|
+
i0.ɵɵtemplate(6, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_td_6_Template, 3, 8, "td", 210);
|
|
845
|
+
i0.ɵɵelement(7, "td", 193);
|
|
845
846
|
i0.ɵɵelementEnd();
|
|
846
847
|
} if (rf & 2) {
|
|
847
848
|
const test_r23 = ctx.$implicit;
|
|
@@ -856,8 +857,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
856
857
|
i0.ɵɵadvance();
|
|
857
858
|
i0.ɵɵproperty("ngForOf", ctx_r0.matrixData);
|
|
858
859
|
} }
|
|
859
|
-
function
|
|
860
|
-
i0.ɵɵelementStart(0, "span",
|
|
860
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_2_Template(rf, ctx) { if (rf & 1) {
|
|
861
|
+
i0.ɵɵelementStart(0, "span", 234)(1, "span", 235);
|
|
861
862
|
i0.ɵɵtext(2);
|
|
862
863
|
i0.ɵɵelementEnd()();
|
|
863
864
|
} if (rf & 2) {
|
|
@@ -866,8 +867,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
866
867
|
i0.ɵɵadvance(2);
|
|
867
868
|
i0.ɵɵtextInterpolate2("", ctx_r0.getRunPassedCount(run_r27), "/", ctx_r0.getRunTotalCount(run_r27), "");
|
|
868
869
|
} }
|
|
869
|
-
function
|
|
870
|
-
i0.ɵɵelementStart(0, "span",
|
|
870
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_3_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
871
|
+
i0.ɵɵelementStart(0, "span", 239);
|
|
871
872
|
i0.ɵɵtext(1);
|
|
872
873
|
i0.ɵɵelementEnd();
|
|
873
874
|
} if (rf & 2) {
|
|
@@ -877,10 +878,10 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
877
878
|
i0.ɵɵadvance();
|
|
878
879
|
i0.ɵɵtextInterpolate((tmp_8_0 = ctx_r0.getRunHumanAvg(run_r27)) == null ? null : tmp_8_0.toFixed(1));
|
|
879
880
|
} }
|
|
880
|
-
function
|
|
881
|
-
i0.ɵɵelementStart(0, "span",
|
|
882
|
-
i0.ɵɵtemplate(1,
|
|
883
|
-
i0.ɵɵelementStart(2, "span",
|
|
881
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_3_Template(rf, ctx) { if (rf & 1) {
|
|
882
|
+
i0.ɵɵelementStart(0, "span", 236);
|
|
883
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_3_span_1_Template, 2, 1, "span", 237);
|
|
884
|
+
i0.ɵɵelementStart(2, "span", 238);
|
|
884
885
|
i0.ɵɵtext(3);
|
|
885
886
|
i0.ɵɵelementEnd()();
|
|
886
887
|
} if (rf & 2) {
|
|
@@ -891,8 +892,8 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
891
892
|
i0.ɵɵadvance(2);
|
|
892
893
|
i0.ɵɵtextInterpolate1("(", ctx_r0.getRunHumanCount(run_r27), ")");
|
|
893
894
|
} }
|
|
894
|
-
function
|
|
895
|
-
i0.ɵɵelementStart(0, "span",
|
|
895
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_4_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
896
|
+
i0.ɵɵelementStart(0, "span", 239);
|
|
896
897
|
i0.ɵɵtext(1);
|
|
897
898
|
i0.ɵɵelementEnd();
|
|
898
899
|
} if (rf & 2) {
|
|
@@ -901,10 +902,10 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
901
902
|
i0.ɵɵadvance();
|
|
902
903
|
i0.ɵɵtextInterpolate1("", (ctx_r0.getRunAutoAvg(run_r27) * 100).toFixed(0), "%");
|
|
903
904
|
} }
|
|
904
|
-
function
|
|
905
|
-
i0.ɵɵelementStart(0, "span",
|
|
906
|
-
i0.ɵɵtemplate(1,
|
|
907
|
-
i0.ɵɵelementStart(2, "span",
|
|
905
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_4_Template(rf, ctx) { if (rf & 1) {
|
|
906
|
+
i0.ɵɵelementStart(0, "span", 240);
|
|
907
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_4_span_1_Template, 2, 1, "span", 237);
|
|
908
|
+
i0.ɵɵelementStart(2, "span", 238);
|
|
908
909
|
i0.ɵɵtext(3);
|
|
909
910
|
i0.ɵɵelementEnd()();
|
|
910
911
|
} if (rf & 2) {
|
|
@@ -915,9 +916,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
915
916
|
i0.ɵɵadvance(2);
|
|
916
917
|
i0.ɵɵtextInterpolate1("(", ctx_r0.getRunAutoCount(run_r27), ")");
|
|
917
918
|
} }
|
|
918
|
-
function
|
|
919
|
-
i0.ɵɵelementStart(0, "td",
|
|
920
|
-
i0.ɵɵtemplate(2,
|
|
919
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_Template(rf, ctx) { if (rf & 1) {
|
|
920
|
+
i0.ɵɵelementStart(0, "td", 229)(1, "div", 230);
|
|
921
|
+
i0.ɵɵtemplate(2, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_2_Template, 3, 2, "span", 231)(3, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_3_Template, 4, 2, "span", 232)(4, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_span_4_Template, 4, 2, "span", 233);
|
|
921
922
|
i0.ɵɵelementEnd()();
|
|
922
923
|
} if (rf & 2) {
|
|
923
924
|
const ctx_r0 = i0.ɵɵnextContext(5);
|
|
@@ -928,50 +929,50 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
928
929
|
i0.ɵɵadvance();
|
|
929
930
|
i0.ɵɵproperty("ngIf", ctx_r0.evalPreferences.showAuto);
|
|
930
931
|
} }
|
|
931
|
-
function
|
|
932
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
932
933
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
933
|
-
i0.ɵɵelementStart(0, "div",
|
|
934
|
-
i0.ɵɵelement(3, "i",
|
|
934
|
+
i0.ɵɵelementStart(0, "div", 172)(1, "div", 173)(2, "h3");
|
|
935
|
+
i0.ɵɵelement(3, "i", 121);
|
|
935
936
|
i0.ɵɵtext(4, " Test Results Matrix");
|
|
936
937
|
i0.ɵɵelementEnd();
|
|
937
|
-
i0.ɵɵelementStart(5, "div",
|
|
938
|
-
i0.ɵɵelement(7, "i",
|
|
939
|
-
i0.ɵɵelementStart(8, "input",
|
|
940
|
-
i0.ɵɵlistener("input", function
|
|
938
|
+
i0.ɵɵelementStart(5, "div", 174)(6, "div", 175);
|
|
939
|
+
i0.ɵɵelement(7, "i", 176);
|
|
940
|
+
i0.ɵɵelementStart(8, "input", 177);
|
|
941
|
+
i0.ɵɵlistener("input", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.onMatrixFilterInput($event)); });
|
|
941
942
|
i0.ɵɵelementEnd();
|
|
942
|
-
i0.ɵɵtemplate(9,
|
|
943
|
+
i0.ɵɵtemplate(9, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_button_9_Template, 2, 0, "button", 178);
|
|
943
944
|
i0.ɵɵelementEnd();
|
|
944
|
-
i0.ɵɵelementStart(10, "span",
|
|
945
|
+
i0.ɵɵelementStart(10, "span", 179);
|
|
945
946
|
i0.ɵɵtext(11);
|
|
946
947
|
i0.ɵɵelementEnd();
|
|
947
|
-
i0.ɵɵelementStart(12, "button",
|
|
948
|
-
i0.ɵɵlistener("click", function
|
|
949
|
-
i0.ɵɵelement(13, "i",
|
|
948
|
+
i0.ɵɵelementStart(12, "button", 180);
|
|
949
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.exportMatrixToCSV()); });
|
|
950
|
+
i0.ɵɵelement(13, "i", 181);
|
|
950
951
|
i0.ɵɵtext(14, " Export ");
|
|
951
952
|
i0.ɵɵelementEnd()()();
|
|
952
|
-
i0.ɵɵelementStart(15, "div",
|
|
953
|
-
i0.ɵɵlistener("click", function
|
|
953
|
+
i0.ɵɵelementStart(15, "div", 182)(16, "table", 183)(17, "thead")(18, "tr")(19, "th", 184);
|
|
954
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_Template_th_click_19_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("sequence")); });
|
|
954
955
|
i0.ɵɵtext(20, " # ");
|
|
955
|
-
i0.ɵɵelement(21, "i",
|
|
956
|
+
i0.ɵɵelement(21, "i", 16);
|
|
956
957
|
i0.ɵɵelementEnd();
|
|
957
|
-
i0.ɵɵelementStart(22, "th",
|
|
958
|
-
i0.ɵɵlistener("click", function
|
|
958
|
+
i0.ɵɵelementStart(22, "th", 185);
|
|
959
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_Template_th_click_22_listener() { i0.ɵɵrestoreView(_r17); const ctx_r0 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r0.toggleMatrixSort("name")); });
|
|
959
960
|
i0.ɵɵtext(23, " Test ");
|
|
960
|
-
i0.ɵɵelement(24, "i",
|
|
961
|
+
i0.ɵɵelement(24, "i", 16);
|
|
961
962
|
i0.ɵɵelementEnd();
|
|
962
|
-
i0.ɵɵtemplate(25,
|
|
963
|
-
i0.ɵɵelement(26, "th",
|
|
963
|
+
i0.ɵɵtemplate(25, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_th_25_Template, 8, 12, "th", 186);
|
|
964
|
+
i0.ɵɵelement(26, "th", 187);
|
|
964
965
|
i0.ɵɵelementEnd()();
|
|
965
966
|
i0.ɵɵelementStart(27, "tbody");
|
|
966
|
-
i0.ɵɵtemplate(28,
|
|
967
|
+
i0.ɵɵtemplate(28, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_tr_28_Template, 8, 6, "tr", 188);
|
|
967
968
|
i0.ɵɵelementEnd();
|
|
968
|
-
i0.ɵɵelementStart(29, "tfoot")(30, "tr",
|
|
969
|
-
i0.ɵɵelement(31, "td",
|
|
970
|
-
i0.ɵɵelementStart(32, "td",
|
|
969
|
+
i0.ɵɵelementStart(29, "tfoot")(30, "tr", 189);
|
|
970
|
+
i0.ɵɵelement(31, "td", 190);
|
|
971
|
+
i0.ɵɵelementStart(32, "td", 191)(33, "strong");
|
|
971
972
|
i0.ɵɵtext(34, "Totals");
|
|
972
973
|
i0.ɵɵelementEnd()();
|
|
973
|
-
i0.ɵɵtemplate(35,
|
|
974
|
-
i0.ɵɵelement(36, "td",
|
|
974
|
+
i0.ɵɵtemplate(35, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_td_35_Template, 5, 3, "td", 192);
|
|
975
|
+
i0.ɵɵelement(36, "td", 193);
|
|
975
976
|
i0.ɵɵelementEnd()()()()();
|
|
976
977
|
} if (rf & 2) {
|
|
977
978
|
const ctx_r0 = i0.ɵɵnextContext(4);
|
|
@@ -994,9 +995,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
994
995
|
i0.ɵɵadvance(7);
|
|
995
996
|
i0.ɵɵproperty("ngForOf", ctx_r0.matrixData);
|
|
996
997
|
} }
|
|
997
|
-
function
|
|
998
|
-
i0.ɵɵelementStart(0, "div",
|
|
999
|
-
i0.ɵɵelement(2, "i",
|
|
998
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
999
|
+
i0.ɵɵelementStart(0, "div", 83)(1, "div", 84);
|
|
1000
|
+
i0.ɵɵelement(2, "i", 121);
|
|
1000
1001
|
i0.ɵɵelementEnd();
|
|
1001
1002
|
i0.ɵɵelementStart(3, "h4");
|
|
1002
1003
|
i0.ɵɵtext(4, "No Matrix Data");
|
|
@@ -1005,9 +1006,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_di
|
|
|
1005
1006
|
i0.ɵɵtext(6, "No suite runs match the current filters.");
|
|
1006
1007
|
i0.ɵɵelementEnd()();
|
|
1007
1008
|
} }
|
|
1008
|
-
function
|
|
1009
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_Template(rf, ctx) { if (rf & 1) {
|
|
1009
1010
|
i0.ɵɵelementContainerStart(0);
|
|
1010
|
-
i0.ɵɵtemplate(1,
|
|
1011
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_1_Template, 2, 0, "div", 61)(2, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_2_Template, 37, 10, "div", 170)(3, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_div_3_Template, 7, 0, "div", 63);
|
|
1011
1012
|
i0.ɵɵelementContainerEnd();
|
|
1012
1013
|
} if (rf & 2) {
|
|
1013
1014
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -1018,37 +1019,37 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_24_Te
|
|
|
1018
1019
|
i0.ɵɵadvance();
|
|
1019
1020
|
i0.ɵɵproperty("ngIf", !ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0);
|
|
1020
1021
|
} }
|
|
1021
|
-
function
|
|
1022
|
-
i0.ɵɵelementStart(0, "div",
|
|
1023
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
1022
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
1023
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
1024
|
+
i0.ɵɵelement(1, "mj-loading", 242);
|
|
1024
1025
|
i0.ɵɵelementEnd();
|
|
1025
1026
|
} }
|
|
1026
|
-
function
|
|
1027
|
-
i0.ɵɵelementStart(0, "div",
|
|
1028
|
-
i0.ɵɵelement(3, "i",
|
|
1027
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
1028
|
+
i0.ɵɵelementStart(0, "div", 243)(1, "div", 244)(2, "h3");
|
|
1029
|
+
i0.ɵɵelement(3, "i", 122);
|
|
1029
1030
|
i0.ɵɵtext(4, " Test Results Flow");
|
|
1030
1031
|
i0.ɵɵelementEnd();
|
|
1031
|
-
i0.ɵɵelementStart(5, "div",
|
|
1032
|
-
i0.ɵɵelement(7, "i",
|
|
1032
|
+
i0.ɵɵelementStart(5, "div", 245)(6, "span", 246);
|
|
1033
|
+
i0.ɵɵelement(7, "i", 142);
|
|
1033
1034
|
i0.ɵɵtext(8, " Passed");
|
|
1034
1035
|
i0.ɵɵelementEnd();
|
|
1035
|
-
i0.ɵɵelementStart(9, "span",
|
|
1036
|
-
i0.ɵɵelement(10, "i",
|
|
1036
|
+
i0.ɵɵelementStart(9, "span", 247);
|
|
1037
|
+
i0.ɵɵelement(10, "i", 195);
|
|
1037
1038
|
i0.ɵɵtext(11, " Failed");
|
|
1038
1039
|
i0.ɵɵelementEnd();
|
|
1039
|
-
i0.ɵɵelementStart(12, "span",
|
|
1040
|
-
i0.ɵɵelement(13, "i",
|
|
1040
|
+
i0.ɵɵelementStart(12, "span", 248);
|
|
1041
|
+
i0.ɵɵelement(13, "i", 249);
|
|
1041
1042
|
i0.ɵɵtext(14, " Error");
|
|
1042
1043
|
i0.ɵɵelementEnd();
|
|
1043
|
-
i0.ɵɵelementStart(15, "span",
|
|
1044
|
-
i0.ɵɵelement(16, "i",
|
|
1044
|
+
i0.ɵɵelementStart(15, "span", 250);
|
|
1045
|
+
i0.ɵɵelement(16, "i", 251);
|
|
1045
1046
|
i0.ɵɵtext(17, " Skipped");
|
|
1046
1047
|
i0.ɵɵelementEnd()()();
|
|
1047
|
-
i0.ɵɵelementStart(18, "div",
|
|
1048
|
-
i0.ɵɵelement(19, "div",
|
|
1048
|
+
i0.ɵɵelementStart(18, "div", 252);
|
|
1049
|
+
i0.ɵɵelement(19, "div", 253, 0);
|
|
1049
1050
|
i0.ɵɵelementEnd();
|
|
1050
|
-
i0.ɵɵelementStart(21, "div",
|
|
1051
|
-
i0.ɵɵelement(22, "i",
|
|
1051
|
+
i0.ɵɵelementStart(21, "div", 254);
|
|
1052
|
+
i0.ɵɵelement(22, "i", 48);
|
|
1052
1053
|
i0.ɵɵtext(23);
|
|
1053
1054
|
i0.ɵɵelementEnd()();
|
|
1054
1055
|
} if (rf & 2) {
|
|
@@ -1056,9 +1057,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_25_di
|
|
|
1056
1057
|
i0.ɵɵadvance(23);
|
|
1057
1058
|
i0.ɵɵtextInterpolate1(" Interactive visualization showing test results across ", ctx_r0.matrixData.length, " runs. Hover over elements for details, click nodes to navigate. ");
|
|
1058
1059
|
} }
|
|
1059
|
-
function
|
|
1060
|
-
i0.ɵɵelementStart(0, "div",
|
|
1061
|
-
i0.ɵɵelement(2, "i",
|
|
1060
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
1061
|
+
i0.ɵɵelementStart(0, "div", 83)(1, "div", 84);
|
|
1062
|
+
i0.ɵɵelement(2, "i", 122);
|
|
1062
1063
|
i0.ɵɵelementEnd();
|
|
1063
1064
|
i0.ɵɵelementStart(3, "h4");
|
|
1064
1065
|
i0.ɵɵtext(4, "No Chart Data");
|
|
@@ -1067,9 +1068,9 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_25_di
|
|
|
1067
1068
|
i0.ɵɵtext(6, "No suite runs match the current filters.");
|
|
1068
1069
|
i0.ɵɵelementEnd()();
|
|
1069
1070
|
} }
|
|
1070
|
-
function
|
|
1071
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_Template(rf, ctx) { if (rf & 1) {
|
|
1071
1072
|
i0.ɵɵelementContainerStart(0);
|
|
1072
|
-
i0.ɵɵtemplate(1,
|
|
1073
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_div_1_Template, 2, 0, "div", 61)(2, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_div_2_Template, 24, 1, "div", 241)(3, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_div_3_Template, 7, 0, "div", 63);
|
|
1073
1074
|
i0.ɵɵelementContainerEnd();
|
|
1074
1075
|
} if (rf & 2) {
|
|
1075
1076
|
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
@@ -1080,39 +1081,39 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_ng_container_25_Te
|
|
|
1080
1081
|
i0.ɵɵadvance();
|
|
1081
1082
|
i0.ɵɵproperty("ngIf", !ctx_r0.loadingMatrix && ctx_r0.matrixLoaded && ctx_r0.matrixData.length === 0);
|
|
1082
1083
|
} }
|
|
1083
|
-
function
|
|
1084
|
+
function TestSuiteFormComponentExtended_div_61_ng_container_2_Template(rf, ctx) { if (rf & 1) {
|
|
1084
1085
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
1085
1086
|
i0.ɵɵelementContainerStart(0);
|
|
1086
|
-
i0.ɵɵelementStart(1, "div",
|
|
1087
|
-
i0.ɵɵlistener("click", function
|
|
1088
|
-
i0.ɵɵelement(4, "i",
|
|
1087
|
+
i0.ɵɵelementStart(1, "div", 117)(2, "div", 118)(3, "button", 119);
|
|
1088
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("summary")); });
|
|
1089
|
+
i0.ɵɵelement(4, "i", 120);
|
|
1089
1090
|
i0.ɵɵelementStart(5, "span");
|
|
1090
1091
|
i0.ɵɵtext(6, "Summary");
|
|
1091
1092
|
i0.ɵɵelementEnd()();
|
|
1092
|
-
i0.ɵɵelementStart(7, "button",
|
|
1093
|
-
i0.ɵɵlistener("click", function
|
|
1094
|
-
i0.ɵɵelement(8, "i",
|
|
1093
|
+
i0.ɵɵelementStart(7, "button", 119);
|
|
1094
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("matrix")); });
|
|
1095
|
+
i0.ɵɵelement(8, "i", 121);
|
|
1095
1096
|
i0.ɵɵelementStart(9, "span");
|
|
1096
1097
|
i0.ɵɵtext(10, "Matrix");
|
|
1097
1098
|
i0.ɵɵelementEnd()();
|
|
1098
|
-
i0.ɵɵelementStart(11, "button",
|
|
1099
|
-
i0.ɵɵlistener("click", function
|
|
1100
|
-
i0.ɵɵelement(12, "i",
|
|
1099
|
+
i0.ɵɵelementStart(11, "button", 119);
|
|
1100
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.setAnalyticsView("chart")); });
|
|
1101
|
+
i0.ɵɵelement(12, "i", 122);
|
|
1101
1102
|
i0.ɵɵelementStart(13, "span");
|
|
1102
1103
|
i0.ɵɵtext(14, "Chart");
|
|
1103
1104
|
i0.ɵɵelementEnd()()()();
|
|
1104
|
-
i0.ɵɵelementStart(15, "div",
|
|
1105
|
-
i0.ɵɵlistener("click", function
|
|
1106
|
-
i0.ɵɵelementStart(17, "span",
|
|
1107
|
-
i0.ɵɵelement(18, "i",
|
|
1105
|
+
i0.ɵɵelementStart(15, "div", 123)(16, "div", 124);
|
|
1106
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_ng_container_2_Template_div_click_16_listener() { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.toggleFilters()); });
|
|
1107
|
+
i0.ɵɵelementStart(17, "span", 125);
|
|
1108
|
+
i0.ɵɵelement(18, "i", 126);
|
|
1108
1109
|
i0.ɵɵtext(19, " Filters ");
|
|
1109
|
-
i0.ɵɵtemplate(20,
|
|
1110
|
+
i0.ɵɵtemplate(20, TestSuiteFormComponentExtended_div_61_ng_container_2_span_20_Template, 3, 2, "span", 127);
|
|
1110
1111
|
i0.ɵɵelementEnd();
|
|
1111
|
-
i0.ɵɵelement(21, "i",
|
|
1112
|
+
i0.ɵɵelement(21, "i", 16);
|
|
1112
1113
|
i0.ɵɵelementEnd();
|
|
1113
|
-
i0.ɵɵtemplate(22,
|
|
1114
|
+
i0.ɵɵtemplate(22, TestSuiteFormComponentExtended_div_61_ng_container_2_div_22_Template, 14, 9, "div", 128);
|
|
1114
1115
|
i0.ɵɵelementEnd();
|
|
1115
|
-
i0.ɵɵtemplate(23,
|
|
1116
|
+
i0.ɵɵtemplate(23, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_23_Template, 62, 16, "ng-container", 81)(24, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_24_Template, 4, 3, "ng-container", 81)(25, TestSuiteFormComponentExtended_div_61_ng_container_2_ng_container_25_Template, 4, 3, "ng-container", 81);
|
|
1116
1117
|
i0.ɵɵelementContainerEnd();
|
|
1117
1118
|
} if (rf & 2) {
|
|
1118
1119
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
@@ -1137,10 +1138,10 @@ function TestSuiteFormComponentExtended_div_49_ng_container_2_Template(rf, ctx)
|
|
|
1137
1138
|
i0.ɵɵadvance();
|
|
1138
1139
|
i0.ɵɵproperty("ngIf", ctx_r0.analyticsView === "chart");
|
|
1139
1140
|
} }
|
|
1140
|
-
function
|
|
1141
|
+
function TestSuiteFormComponentExtended_div_61_div_3_Template(rf, ctx) { if (rf & 1) {
|
|
1141
1142
|
const _r28 = i0.ɵɵgetCurrentView();
|
|
1142
|
-
i0.ɵɵelementStart(0, "div",
|
|
1143
|
-
i0.ɵɵelement(2, "i",
|
|
1143
|
+
i0.ɵɵelementStart(0, "div", 83)(1, "div", 84);
|
|
1144
|
+
i0.ɵɵelement(2, "i", 32);
|
|
1144
1145
|
i0.ɵɵelementEnd();
|
|
1145
1146
|
i0.ɵɵelementStart(3, "h4");
|
|
1146
1147
|
i0.ɵɵtext(4, "No Analytics Data");
|
|
@@ -1148,15 +1149,15 @@ function TestSuiteFormComponentExtended_div_49_div_3_Template(rf, ctx) { if (rf
|
|
|
1148
1149
|
i0.ɵɵelementStart(5, "p");
|
|
1149
1150
|
i0.ɵɵtext(6, "Run this suite to start collecting analytics data.");
|
|
1150
1151
|
i0.ɵɵelementEnd();
|
|
1151
|
-
i0.ɵɵelementStart(7, "button",
|
|
1152
|
-
i0.ɵɵlistener("click", function
|
|
1153
|
-
i0.ɵɵelement(8, "i",
|
|
1152
|
+
i0.ɵɵelementStart(7, "button", 21);
|
|
1153
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_61_div_3_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r28); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
|
|
1154
|
+
i0.ɵɵelement(8, "i", 22);
|
|
1154
1155
|
i0.ɵɵtext(9, " Run Suite Now ");
|
|
1155
1156
|
i0.ɵɵelementEnd()();
|
|
1156
1157
|
} }
|
|
1157
|
-
function
|
|
1158
|
-
i0.ɵɵelementStart(0, "div",
|
|
1159
|
-
i0.ɵɵtemplate(1,
|
|
1158
|
+
function TestSuiteFormComponentExtended_div_61_Template(rf, ctx) { if (rf & 1) {
|
|
1159
|
+
i0.ɵɵelementStart(0, "div", 115);
|
|
1160
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_61_div_1_Template, 2, 0, "div", 61)(2, TestSuiteFormComponentExtended_div_61_ng_container_2_Template, 26, 14, "ng-container", 81)(3, TestSuiteFormComponentExtended_div_61_div_3_Template, 10, 0, "div", 63);
|
|
1160
1161
|
i0.ɵɵelementEnd();
|
|
1161
1162
|
} if (rf & 2) {
|
|
1162
1163
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -1167,8 +1168,8 @@ function TestSuiteFormComponentExtended_div_49_Template(rf, ctx) { if (rf & 1) {
|
|
|
1167
1168
|
i0.ɵɵadvance();
|
|
1168
1169
|
i0.ɵɵproperty("ngIf", !ctx_r0.loadingAnalytics && ctx_r0.analyticsLoaded && ctx_r0.analyticsData.length === 0);
|
|
1169
1170
|
} }
|
|
1170
|
-
function
|
|
1171
|
-
i0.ɵɵelementStart(0, "span",
|
|
1171
|
+
function TestSuiteFormComponentExtended_div_62_div_5_div_1_div_8_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
1172
|
+
i0.ɵɵelementStart(0, "span", 274);
|
|
1172
1173
|
i0.ɵɵtext(1);
|
|
1173
1174
|
i0.ɵɵelementEnd();
|
|
1174
1175
|
} if (rf & 2) {
|
|
@@ -1176,9 +1177,9 @@ function TestSuiteFormComponentExtended_div_50_div_5_div_1_div_8_span_1_Template
|
|
|
1176
1177
|
i0.ɵɵadvance();
|
|
1177
1178
|
i0.ɵɵtextInterpolate(tag_r31);
|
|
1178
1179
|
} }
|
|
1179
|
-
function
|
|
1180
|
-
i0.ɵɵelementStart(0, "div",
|
|
1181
|
-
i0.ɵɵtemplate(1,
|
|
1180
|
+
function TestSuiteFormComponentExtended_div_62_div_5_div_1_div_8_Template(rf, ctx) { if (rf & 1) {
|
|
1181
|
+
i0.ɵɵelementStart(0, "div", 272);
|
|
1182
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_62_div_5_div_1_div_8_span_1_Template, 2, 1, "span", 273);
|
|
1182
1183
|
i0.ɵɵelementEnd();
|
|
1183
1184
|
} if (rf & 2) {
|
|
1184
1185
|
const run_r30 = i0.ɵɵnextContext().$implicit;
|
|
@@ -1186,19 +1187,19 @@ function TestSuiteFormComponentExtended_div_50_div_5_div_1_div_8_Template(rf, ct
|
|
|
1186
1187
|
i0.ɵɵadvance();
|
|
1187
1188
|
i0.ɵɵproperty("ngForOf", ctx_r0.getRunTags(run_r30).slice(0, 2));
|
|
1188
1189
|
} }
|
|
1189
|
-
function
|
|
1190
|
+
function TestSuiteFormComponentExtended_div_62_div_5_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
1190
1191
|
const _r29 = i0.ɵɵgetCurrentView();
|
|
1191
|
-
i0.ɵɵelementStart(0, "div",
|
|
1192
|
-
i0.ɵɵlistener("click", function
|
|
1193
|
-
i0.ɵɵelement(1, "div",
|
|
1194
|
-
i0.ɵɵelementStart(2, "div",
|
|
1192
|
+
i0.ɵɵelementStart(0, "div", 266);
|
|
1193
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_62_div_5_div_1_Template_div_click_0_listener() { const run_r30 = i0.ɵɵrestoreView(_r29).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.selectCompareRunA(run_r30)); });
|
|
1194
|
+
i0.ɵɵelement(1, "div", 267);
|
|
1195
|
+
i0.ɵɵelementStart(2, "div", 268)(3, "div", 269);
|
|
1195
1196
|
i0.ɵɵtext(4);
|
|
1196
1197
|
i0.ɵɵpipe(5, "date");
|
|
1197
1198
|
i0.ɵɵelementEnd();
|
|
1198
|
-
i0.ɵɵelementStart(6, "div",
|
|
1199
|
+
i0.ɵɵelementStart(6, "div", 270);
|
|
1199
1200
|
i0.ɵɵtext(7);
|
|
1200
1201
|
i0.ɵɵelementEnd()();
|
|
1201
|
-
i0.ɵɵtemplate(8,
|
|
1202
|
+
i0.ɵɵtemplate(8, TestSuiteFormComponentExtended_div_62_div_5_div_1_div_8_Template, 2, 1, "div", 271);
|
|
1202
1203
|
i0.ɵɵelementEnd();
|
|
1203
1204
|
} if (rf & 2) {
|
|
1204
1205
|
const run_r30 = ctx.$implicit;
|
|
@@ -1213,29 +1214,29 @@ function TestSuiteFormComponentExtended_div_50_div_5_div_1_Template(rf, ctx) { i
|
|
|
1213
1214
|
i0.ɵɵadvance();
|
|
1214
1215
|
i0.ɵɵproperty("ngIf", ctx_r0.getRunTags(run_r30).length > 0);
|
|
1215
1216
|
} }
|
|
1216
|
-
function
|
|
1217
|
-
i0.ɵɵelementStart(0, "div",
|
|
1218
|
-
i0.ɵɵtemplate(1,
|
|
1217
|
+
function TestSuiteFormComponentExtended_div_62_div_5_Template(rf, ctx) { if (rf & 1) {
|
|
1218
|
+
i0.ɵɵelementStart(0, "div", 264);
|
|
1219
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_62_div_5_div_1_Template, 9, 10, "div", 265);
|
|
1219
1220
|
i0.ɵɵelementEnd();
|
|
1220
1221
|
} if (rf & 2) {
|
|
1221
1222
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
1222
1223
|
i0.ɵɵadvance();
|
|
1223
1224
|
i0.ɵɵproperty("ngForOf", ctx_r0.suiteRuns);
|
|
1224
1225
|
} }
|
|
1225
|
-
function
|
|
1226
|
+
function TestSuiteFormComponentExtended_div_62_div_6_Template(rf, ctx) { if (rf & 1) {
|
|
1226
1227
|
const _r32 = i0.ɵɵgetCurrentView();
|
|
1227
|
-
i0.ɵɵelementStart(0, "div",
|
|
1228
|
+
i0.ɵɵelementStart(0, "div", 275)(1, "div", 276)(2, "span", 277);
|
|
1228
1229
|
i0.ɵɵtext(3, "Selected:");
|
|
1229
1230
|
i0.ɵɵelementEnd();
|
|
1230
|
-
i0.ɵɵelementStart(4, "button",
|
|
1231
|
-
i0.ɵɵlistener("click", function
|
|
1231
|
+
i0.ɵɵelementStart(4, "button", 278);
|
|
1232
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_62_div_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r32); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunA = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
|
|
1232
1233
|
i0.ɵɵtext(5, "Clear");
|
|
1233
1234
|
i0.ɵɵelementEnd()();
|
|
1234
|
-
i0.ɵɵelementStart(6, "div",
|
|
1235
|
+
i0.ɵɵelementStart(6, "div", 279)(7, "span");
|
|
1235
1236
|
i0.ɵɵtext(8);
|
|
1236
1237
|
i0.ɵɵpipe(9, "date");
|
|
1237
1238
|
i0.ɵɵelementEnd();
|
|
1238
|
-
i0.ɵɵelementStart(10, "span",
|
|
1239
|
+
i0.ɵɵelementStart(10, "span", 280);
|
|
1239
1240
|
i0.ɵɵtext(11);
|
|
1240
1241
|
i0.ɵɵelementEnd()()();
|
|
1241
1242
|
} if (rf & 2) {
|
|
@@ -1245,8 +1246,8 @@ function TestSuiteFormComponentExtended_div_50_div_6_Template(rf, ctx) { if (rf
|
|
|
1245
1246
|
i0.ɵɵadvance(3);
|
|
1246
1247
|
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunA).toFixed(1), "%");
|
|
1247
1248
|
} }
|
|
1248
|
-
function
|
|
1249
|
-
i0.ɵɵelementStart(0, "span",
|
|
1249
|
+
function TestSuiteFormComponentExtended_div_62_div_12_div_1_div_8_span_1_Template(rf, ctx) { if (rf & 1) {
|
|
1250
|
+
i0.ɵɵelementStart(0, "span", 274);
|
|
1250
1251
|
i0.ɵɵtext(1);
|
|
1251
1252
|
i0.ɵɵelementEnd();
|
|
1252
1253
|
} if (rf & 2) {
|
|
@@ -1254,9 +1255,9 @@ function TestSuiteFormComponentExtended_div_50_div_12_div_1_div_8_span_1_Templat
|
|
|
1254
1255
|
i0.ɵɵadvance();
|
|
1255
1256
|
i0.ɵɵtextInterpolate(tag_r35);
|
|
1256
1257
|
} }
|
|
1257
|
-
function
|
|
1258
|
-
i0.ɵɵelementStart(0, "div",
|
|
1259
|
-
i0.ɵɵtemplate(1,
|
|
1258
|
+
function TestSuiteFormComponentExtended_div_62_div_12_div_1_div_8_Template(rf, ctx) { if (rf & 1) {
|
|
1259
|
+
i0.ɵɵelementStart(0, "div", 272);
|
|
1260
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_62_div_12_div_1_div_8_span_1_Template, 2, 1, "span", 273);
|
|
1260
1261
|
i0.ɵɵelementEnd();
|
|
1261
1262
|
} if (rf & 2) {
|
|
1262
1263
|
const run_r34 = i0.ɵɵnextContext().$implicit;
|
|
@@ -1264,19 +1265,19 @@ function TestSuiteFormComponentExtended_div_50_div_12_div_1_div_8_Template(rf, c
|
|
|
1264
1265
|
i0.ɵɵadvance();
|
|
1265
1266
|
i0.ɵɵproperty("ngForOf", ctx_r0.getRunTags(run_r34).slice(0, 2));
|
|
1266
1267
|
} }
|
|
1267
|
-
function
|
|
1268
|
+
function TestSuiteFormComponentExtended_div_62_div_12_div_1_Template(rf, ctx) { if (rf & 1) {
|
|
1268
1269
|
const _r33 = i0.ɵɵgetCurrentView();
|
|
1269
|
-
i0.ɵɵelementStart(0, "div",
|
|
1270
|
-
i0.ɵɵlistener("click", function
|
|
1271
|
-
i0.ɵɵelement(1, "div",
|
|
1272
|
-
i0.ɵɵelementStart(2, "div",
|
|
1270
|
+
i0.ɵɵelementStart(0, "div", 266);
|
|
1271
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_62_div_12_div_1_Template_div_click_0_listener() { const run_r34 = i0.ɵɵrestoreView(_r33).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView((ctx_r0.compareRunA == null ? null : ctx_r0.compareRunA.ID) !== run_r34.ID && ctx_r0.selectCompareRunB(run_r34)); });
|
|
1272
|
+
i0.ɵɵelement(1, "div", 267);
|
|
1273
|
+
i0.ɵɵelementStart(2, "div", 268)(3, "div", 269);
|
|
1273
1274
|
i0.ɵɵtext(4);
|
|
1274
1275
|
i0.ɵɵpipe(5, "date");
|
|
1275
1276
|
i0.ɵɵelementEnd();
|
|
1276
|
-
i0.ɵɵelementStart(6, "div",
|
|
1277
|
+
i0.ɵɵelementStart(6, "div", 270);
|
|
1277
1278
|
i0.ɵɵtext(7);
|
|
1278
1279
|
i0.ɵɵelementEnd()();
|
|
1279
|
-
i0.ɵɵtemplate(8,
|
|
1280
|
+
i0.ɵɵtemplate(8, TestSuiteFormComponentExtended_div_62_div_12_div_1_div_8_Template, 2, 1, "div", 271);
|
|
1280
1281
|
i0.ɵɵelementEnd();
|
|
1281
1282
|
} if (rf & 2) {
|
|
1282
1283
|
const run_r34 = ctx.$implicit;
|
|
@@ -1291,29 +1292,29 @@ function TestSuiteFormComponentExtended_div_50_div_12_div_1_Template(rf, ctx) {
|
|
|
1291
1292
|
i0.ɵɵadvance();
|
|
1292
1293
|
i0.ɵɵproperty("ngIf", ctx_r0.getRunTags(run_r34).length > 0);
|
|
1293
1294
|
} }
|
|
1294
|
-
function
|
|
1295
|
-
i0.ɵɵelementStart(0, "div",
|
|
1296
|
-
i0.ɵɵtemplate(1,
|
|
1295
|
+
function TestSuiteFormComponentExtended_div_62_div_12_Template(rf, ctx) { if (rf & 1) {
|
|
1296
|
+
i0.ɵɵelementStart(0, "div", 264);
|
|
1297
|
+
i0.ɵɵtemplate(1, TestSuiteFormComponentExtended_div_62_div_12_div_1_Template, 9, 12, "div", 281);
|
|
1297
1298
|
i0.ɵɵelementEnd();
|
|
1298
1299
|
} if (rf & 2) {
|
|
1299
1300
|
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
1300
1301
|
i0.ɵɵadvance();
|
|
1301
1302
|
i0.ɵɵproperty("ngForOf", ctx_r0.suiteRuns);
|
|
1302
1303
|
} }
|
|
1303
|
-
function
|
|
1304
|
+
function TestSuiteFormComponentExtended_div_62_div_13_Template(rf, ctx) { if (rf & 1) {
|
|
1304
1305
|
const _r36 = i0.ɵɵgetCurrentView();
|
|
1305
|
-
i0.ɵɵelementStart(0, "div",
|
|
1306
|
+
i0.ɵɵelementStart(0, "div", 275)(1, "div", 276)(2, "span", 277);
|
|
1306
1307
|
i0.ɵɵtext(3, "Selected:");
|
|
1307
1308
|
i0.ɵɵelementEnd();
|
|
1308
|
-
i0.ɵɵelementStart(4, "button",
|
|
1309
|
-
i0.ɵɵlistener("click", function
|
|
1309
|
+
i0.ɵɵelementStart(4, "button", 278);
|
|
1310
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_62_div_13_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r36); const ctx_r0 = i0.ɵɵnextContext(2); ctx_r0.compareRunB = null; return i0.ɵɵresetView(ctx_r0.compareResults = []); });
|
|
1310
1311
|
i0.ɵɵtext(5, "Clear");
|
|
1311
1312
|
i0.ɵɵelementEnd()();
|
|
1312
|
-
i0.ɵɵelementStart(6, "div",
|
|
1313
|
+
i0.ɵɵelementStart(6, "div", 279)(7, "span");
|
|
1313
1314
|
i0.ɵɵtext(8);
|
|
1314
1315
|
i0.ɵɵpipe(9, "date");
|
|
1315
1316
|
i0.ɵɵelementEnd();
|
|
1316
|
-
i0.ɵɵelementStart(10, "span",
|
|
1317
|
+
i0.ɵɵelementStart(10, "span", 280);
|
|
1317
1318
|
i0.ɵɵtext(11);
|
|
1318
1319
|
i0.ɵɵelementEnd()()();
|
|
1319
1320
|
} if (rf & 2) {
|
|
@@ -1323,8 +1324,8 @@ function TestSuiteFormComponentExtended_div_50_div_13_Template(rf, ctx) { if (rf
|
|
|
1323
1324
|
i0.ɵɵadvance(3);
|
|
1324
1325
|
i0.ɵɵtextInterpolate1("", ctx_r0.getPassRate(ctx_r0.compareRunB).toFixed(1), "%");
|
|
1325
1326
|
} }
|
|
1326
|
-
function
|
|
1327
|
-
i0.ɵɵelementStart(0, "span",
|
|
1327
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_4_Template(rf, ctx) { if (rf & 1) {
|
|
1328
|
+
i0.ɵɵelementStart(0, "span", 161);
|
|
1328
1329
|
i0.ɵɵtext(1);
|
|
1329
1330
|
i0.ɵɵelementEnd();
|
|
1330
1331
|
} if (rf & 2) {
|
|
@@ -1333,13 +1334,13 @@ function TestSuiteFormComponentExtended_div_50_div_14_tr_45_span_4_Template(rf,
|
|
|
1333
1334
|
i0.ɵɵadvance();
|
|
1334
1335
|
i0.ɵɵtextInterpolate(result_r37.runA.status);
|
|
1335
1336
|
} }
|
|
1336
|
-
function
|
|
1337
|
-
i0.ɵɵelementStart(0, "span",
|
|
1337
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_5_Template(rf, ctx) { if (rf & 1) {
|
|
1338
|
+
i0.ɵɵelementStart(0, "span", 303);
|
|
1338
1339
|
i0.ɵɵtext(1, "N/A");
|
|
1339
1340
|
i0.ɵɵelementEnd();
|
|
1340
1341
|
} }
|
|
1341
|
-
function
|
|
1342
|
-
i0.ɵɵelementStart(0, "span",
|
|
1342
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_7_Template(rf, ctx) { if (rf & 1) {
|
|
1343
|
+
i0.ɵɵelementStart(0, "span", 161);
|
|
1343
1344
|
i0.ɵɵtext(1);
|
|
1344
1345
|
i0.ɵɵelementEnd();
|
|
1345
1346
|
} if (rf & 2) {
|
|
@@ -1348,13 +1349,13 @@ function TestSuiteFormComponentExtended_div_50_div_14_tr_45_span_7_Template(rf,
|
|
|
1348
1349
|
i0.ɵɵadvance();
|
|
1349
1350
|
i0.ɵɵtextInterpolate(result_r37.runB.status);
|
|
1350
1351
|
} }
|
|
1351
|
-
function
|
|
1352
|
-
i0.ɵɵelementStart(0, "span",
|
|
1352
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_8_Template(rf, ctx) { if (rf & 1) {
|
|
1353
|
+
i0.ɵɵelementStart(0, "span", 303);
|
|
1353
1354
|
i0.ɵɵtext(1, "N/A");
|
|
1354
1355
|
i0.ɵɵelementEnd();
|
|
1355
1356
|
} }
|
|
1356
|
-
function
|
|
1357
|
-
i0.ɵɵelementStart(0, "span",
|
|
1357
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_10_Template(rf, ctx) { if (rf & 1) {
|
|
1358
|
+
i0.ɵɵelementStart(0, "span", 295);
|
|
1358
1359
|
i0.ɵɵtext(1);
|
|
1359
1360
|
i0.ɵɵelementEnd();
|
|
1360
1361
|
} if (rf & 2) {
|
|
@@ -1363,13 +1364,13 @@ function TestSuiteFormComponentExtended_div_50_div_14_tr_45_span_10_Template(rf,
|
|
|
1363
1364
|
i0.ɵɵadvance();
|
|
1364
1365
|
i0.ɵɵtextInterpolate2(" ", result_r37.scoreDiff > 0 ? "+" : "", "", (result_r37.scoreDiff * 100).toFixed(1), "% ");
|
|
1365
1366
|
} }
|
|
1366
|
-
function
|
|
1367
|
-
i0.ɵɵelementStart(0, "span",
|
|
1367
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_11_Template(rf, ctx) { if (rf & 1) {
|
|
1368
|
+
i0.ɵɵelementStart(0, "span", 304);
|
|
1368
1369
|
i0.ɵɵtext(1, "-");
|
|
1369
1370
|
i0.ɵɵelementEnd();
|
|
1370
1371
|
} }
|
|
1371
|
-
function
|
|
1372
|
-
i0.ɵɵelementStart(0, "span",
|
|
1372
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_13_Template(rf, ctx) { if (rf & 1) {
|
|
1373
|
+
i0.ɵɵelementStart(0, "span", 295);
|
|
1373
1374
|
i0.ɵɵtext(1);
|
|
1374
1375
|
i0.ɵɵelementEnd();
|
|
1375
1376
|
} if (rf & 2) {
|
|
@@ -1378,46 +1379,46 @@ function TestSuiteFormComponentExtended_div_50_div_14_tr_45_span_13_Template(rf,
|
|
|
1378
1379
|
i0.ɵɵadvance();
|
|
1379
1380
|
i0.ɵɵtextInterpolate2(" ", result_r37.durationDiff > 0 ? "+" : "", "", result_r37.durationDiff.toFixed(1), "s ");
|
|
1380
1381
|
} }
|
|
1381
|
-
function
|
|
1382
|
-
i0.ɵɵelementStart(0, "span",
|
|
1382
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_14_Template(rf, ctx) { if (rf & 1) {
|
|
1383
|
+
i0.ɵɵelementStart(0, "span", 304);
|
|
1383
1384
|
i0.ɵɵtext(1, "-");
|
|
1384
1385
|
i0.ɵɵelementEnd();
|
|
1385
1386
|
} }
|
|
1386
|
-
function
|
|
1387
|
-
i0.ɵɵelementStart(0, "span",
|
|
1388
|
-
i0.ɵɵelement(1, "i",
|
|
1387
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_16_Template(rf, ctx) { if (rf & 1) {
|
|
1388
|
+
i0.ɵɵelementStart(0, "span", 305);
|
|
1389
|
+
i0.ɵɵelement(1, "i", 306);
|
|
1389
1390
|
i0.ɵɵtext(2, " Fixed ");
|
|
1390
1391
|
i0.ɵɵelementEnd();
|
|
1391
1392
|
} }
|
|
1392
|
-
function
|
|
1393
|
-
i0.ɵɵelementStart(0, "span",
|
|
1394
|
-
i0.ɵɵelement(1, "i",
|
|
1393
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_17_Template(rf, ctx) { if (rf & 1) {
|
|
1394
|
+
i0.ɵɵelementStart(0, "span", 307);
|
|
1395
|
+
i0.ɵɵelement(1, "i", 308);
|
|
1395
1396
|
i0.ɵɵtext(2, " Broke ");
|
|
1396
1397
|
i0.ɵɵelementEnd();
|
|
1397
1398
|
} }
|
|
1398
|
-
function
|
|
1399
|
-
i0.ɵɵelementStart(0, "span",
|
|
1400
|
-
i0.ɵɵelement(1, "i",
|
|
1399
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_18_Template(rf, ctx) { if (rf & 1) {
|
|
1400
|
+
i0.ɵɵelementStart(0, "span", 309);
|
|
1401
|
+
i0.ɵɵelement(1, "i", 228);
|
|
1401
1402
|
i0.ɵɵelementEnd();
|
|
1402
1403
|
} }
|
|
1403
|
-
function
|
|
1404
|
-
i0.ɵɵelementStart(0, "tr",
|
|
1404
|
+
function TestSuiteFormComponentExtended_div_62_div_14_tr_45_Template(rf, ctx) { if (rf & 1) {
|
|
1405
|
+
i0.ɵɵelementStart(0, "tr", 295)(1, "td", 208);
|
|
1405
1406
|
i0.ɵɵtext(2);
|
|
1406
1407
|
i0.ɵɵelementEnd();
|
|
1407
1408
|
i0.ɵɵelementStart(3, "td");
|
|
1408
|
-
i0.ɵɵtemplate(4,
|
|
1409
|
+
i0.ɵɵtemplate(4, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_4_Template, 2, 2, "span", 296)(5, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_5_Template, 2, 0, "span", 297);
|
|
1409
1410
|
i0.ɵɵelementEnd();
|
|
1410
1411
|
i0.ɵɵelementStart(6, "td");
|
|
1411
|
-
i0.ɵɵtemplate(7,
|
|
1412
|
+
i0.ɵɵtemplate(7, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_7_Template, 2, 2, "span", 296)(8, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_8_Template, 2, 0, "span", 297);
|
|
1412
1413
|
i0.ɵɵelementEnd();
|
|
1413
1414
|
i0.ɵɵelementStart(9, "td");
|
|
1414
|
-
i0.ɵɵtemplate(10,
|
|
1415
|
+
i0.ɵɵtemplate(10, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_10_Template, 2, 6, "span", 298)(11, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_11_Template, 2, 0, "span", 299);
|
|
1415
1416
|
i0.ɵɵelementEnd();
|
|
1416
1417
|
i0.ɵɵelementStart(12, "td");
|
|
1417
|
-
i0.ɵɵtemplate(13,
|
|
1418
|
+
i0.ɵɵtemplate(13, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_13_Template, 2, 6, "span", 298)(14, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_14_Template, 2, 0, "span", 299);
|
|
1418
1419
|
i0.ɵɵelementEnd();
|
|
1419
1420
|
i0.ɵɵelementStart(15, "td");
|
|
1420
|
-
i0.ɵɵtemplate(16,
|
|
1421
|
+
i0.ɵɵtemplate(16, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_16_Template, 3, 0, "span", 300)(17, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_17_Template, 3, 0, "span", 301)(18, TestSuiteFormComponentExtended_div_62_div_14_tr_45_span_18_Template, 2, 0, "span", 302);
|
|
1421
1422
|
i0.ɵɵelementEnd()();
|
|
1422
1423
|
} if (rf & 2) {
|
|
1423
1424
|
const result_r37 = ctx.$implicit;
|
|
@@ -1447,38 +1448,38 @@ function TestSuiteFormComponentExtended_div_50_div_14_tr_45_Template(rf, ctx) {
|
|
|
1447
1448
|
i0.ɵɵadvance();
|
|
1448
1449
|
i0.ɵɵproperty("ngIf", !result_r37.statusChanged);
|
|
1449
1450
|
} }
|
|
1450
|
-
function
|
|
1451
|
-
i0.ɵɵelementStart(0, "div",
|
|
1451
|
+
function TestSuiteFormComponentExtended_div_62_div_14_Template(rf, ctx) { if (rf & 1) {
|
|
1452
|
+
i0.ɵɵelementStart(0, "div", 282)(1, "div", 283)(2, "div", 284)(3, "div", 285);
|
|
1452
1453
|
i0.ɵɵtext(4, "Pass Rate Change");
|
|
1453
1454
|
i0.ɵɵelementEnd();
|
|
1454
|
-
i0.ɵɵelementStart(5, "div",
|
|
1455
|
-
i0.ɵɵelement(6, "i",
|
|
1455
|
+
i0.ɵɵelementStart(5, "div", 286);
|
|
1456
|
+
i0.ɵɵelement(6, "i", 16);
|
|
1456
1457
|
i0.ɵɵtext(7);
|
|
1457
1458
|
i0.ɵɵelementEnd()();
|
|
1458
|
-
i0.ɵɵelementStart(8, "div",
|
|
1459
|
+
i0.ɵɵelementStart(8, "div", 284)(9, "div", 285);
|
|
1459
1460
|
i0.ɵɵtext(10, "Duration Change");
|
|
1460
1461
|
i0.ɵɵelementEnd();
|
|
1461
|
-
i0.ɵɵelementStart(11, "div",
|
|
1462
|
-
i0.ɵɵelement(12, "i",
|
|
1462
|
+
i0.ɵɵelementStart(11, "div", 286);
|
|
1463
|
+
i0.ɵɵelement(12, "i", 16);
|
|
1463
1464
|
i0.ɵɵtext(13);
|
|
1464
1465
|
i0.ɵɵelementEnd()();
|
|
1465
|
-
i0.ɵɵelementStart(14, "div",
|
|
1466
|
+
i0.ɵɵelementStart(14, "div", 287)(15, "div", 285);
|
|
1466
1467
|
i0.ɵɵtext(16, "Improved");
|
|
1467
1468
|
i0.ɵɵelementEnd();
|
|
1468
|
-
i0.ɵɵelementStart(17, "div",
|
|
1469
|
+
i0.ɵɵelementStart(17, "div", 288);
|
|
1469
1470
|
i0.ɵɵtext(18);
|
|
1470
1471
|
i0.ɵɵelementEnd()();
|
|
1471
|
-
i0.ɵɵelementStart(19, "div",
|
|
1472
|
+
i0.ɵɵelementStart(19, "div", 289)(20, "div", 285);
|
|
1472
1473
|
i0.ɵɵtext(21, "Regressed");
|
|
1473
1474
|
i0.ɵɵelementEnd();
|
|
1474
|
-
i0.ɵɵelementStart(22, "div",
|
|
1475
|
+
i0.ɵɵelementStart(22, "div", 288);
|
|
1475
1476
|
i0.ɵɵtext(23);
|
|
1476
1477
|
i0.ɵɵelementEnd()()();
|
|
1477
|
-
i0.ɵɵelementStart(24, "div",
|
|
1478
|
-
i0.ɵɵelement(26, "i",
|
|
1478
|
+
i0.ɵɵelementStart(24, "div", 290)(25, "h3");
|
|
1479
|
+
i0.ɵɵelement(26, "i", 291);
|
|
1479
1480
|
i0.ɵɵtext(27, " Test-by-Test Comparison");
|
|
1480
1481
|
i0.ɵɵelementEnd();
|
|
1481
|
-
i0.ɵɵelementStart(28, "div",
|
|
1482
|
+
i0.ɵɵelementStart(28, "div", 292)(29, "table", 293)(30, "thead")(31, "tr")(32, "th");
|
|
1482
1483
|
i0.ɵɵtext(33, "Test");
|
|
1483
1484
|
i0.ɵɵelementEnd();
|
|
1484
1485
|
i0.ɵɵelementStart(34, "th");
|
|
@@ -1497,7 +1498,7 @@ function TestSuiteFormComponentExtended_div_50_div_14_Template(rf, ctx) { if (rf
|
|
|
1497
1498
|
i0.ɵɵtext(43, "Change");
|
|
1498
1499
|
i0.ɵɵelementEnd()()();
|
|
1499
1500
|
i0.ɵɵelementStart(44, "tbody");
|
|
1500
|
-
i0.ɵɵtemplate(45,
|
|
1501
|
+
i0.ɵɵtemplate(45, TestSuiteFormComponentExtended_div_62_div_14_tr_45_Template, 19, 16, "tr", 294);
|
|
1501
1502
|
i0.ɵɵelementEnd()()()()();
|
|
1502
1503
|
} if (rf & 2) {
|
|
1503
1504
|
let tmp_4_0;
|
|
@@ -1521,14 +1522,14 @@ function TestSuiteFormComponentExtended_div_50_div_14_Template(rf, ctx) { if (rf
|
|
|
1521
1522
|
i0.ɵɵadvance(22);
|
|
1522
1523
|
i0.ɵɵproperty("ngForOf", ctx_r0.compareResults);
|
|
1523
1524
|
} }
|
|
1524
|
-
function
|
|
1525
|
-
i0.ɵɵelementStart(0, "div",
|
|
1526
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
1525
|
+
function TestSuiteFormComponentExtended_div_62_div_15_Template(rf, ctx) { if (rf & 1) {
|
|
1526
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
1527
|
+
i0.ɵɵelement(1, "mj-loading", 310);
|
|
1527
1528
|
i0.ɵɵelementEnd();
|
|
1528
1529
|
} }
|
|
1529
|
-
function
|
|
1530
|
-
i0.ɵɵelementStart(0, "div",
|
|
1531
|
-
i0.ɵɵelement(2, "i",
|
|
1530
|
+
function TestSuiteFormComponentExtended_div_62_div_16_Template(rf, ctx) { if (rf & 1) {
|
|
1531
|
+
i0.ɵɵelementStart(0, "div", 311)(1, "div", 312);
|
|
1532
|
+
i0.ɵɵelement(2, "i", 33);
|
|
1532
1533
|
i0.ɵɵelementEnd();
|
|
1533
1534
|
i0.ɵɵelementStart(3, "h4");
|
|
1534
1535
|
i0.ɵɵtext(4, "Select Two Runs to Compare");
|
|
@@ -1537,10 +1538,10 @@ function TestSuiteFormComponentExtended_div_50_div_16_Template(rf, ctx) { if (rf
|
|
|
1537
1538
|
i0.ɵɵtext(6, "Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.");
|
|
1538
1539
|
i0.ɵɵelementEnd()();
|
|
1539
1540
|
} }
|
|
1540
|
-
function
|
|
1541
|
+
function TestSuiteFormComponentExtended_div_62_div_17_Template(rf, ctx) { if (rf & 1) {
|
|
1541
1542
|
const _r38 = i0.ɵɵgetCurrentView();
|
|
1542
|
-
i0.ɵɵelementStart(0, "div",
|
|
1543
|
-
i0.ɵɵelement(2, "i",
|
|
1543
|
+
i0.ɵɵelementStart(0, "div", 83)(1, "div", 84);
|
|
1544
|
+
i0.ɵɵelement(2, "i", 33);
|
|
1544
1545
|
i0.ɵɵelementEnd();
|
|
1545
1546
|
i0.ɵɵelementStart(3, "h4");
|
|
1546
1547
|
i0.ɵɵtext(4, "Not Enough Runs to Compare");
|
|
@@ -1548,27 +1549,27 @@ function TestSuiteFormComponentExtended_div_50_div_17_Template(rf, ctx) { if (rf
|
|
|
1548
1549
|
i0.ɵɵelementStart(5, "p");
|
|
1549
1550
|
i0.ɵɵtext(6, "You need at least 2 suite runs to use the comparison feature.");
|
|
1550
1551
|
i0.ɵɵelementEnd();
|
|
1551
|
-
i0.ɵɵelementStart(7, "button",
|
|
1552
|
-
i0.ɵɵlistener("click", function
|
|
1553
|
-
i0.ɵɵelement(8, "i",
|
|
1552
|
+
i0.ɵɵelementStart(7, "button", 21);
|
|
1553
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_62_div_17_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r38); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.runSuite()); });
|
|
1554
|
+
i0.ɵɵelement(8, "i", 22);
|
|
1554
1555
|
i0.ɵɵtext(9, " Run Suite Now ");
|
|
1555
1556
|
i0.ɵɵelementEnd()();
|
|
1556
1557
|
} }
|
|
1557
|
-
function
|
|
1558
|
-
i0.ɵɵelementStart(0, "div",
|
|
1558
|
+
function TestSuiteFormComponentExtended_div_62_Template(rf, ctx) { if (rf & 1) {
|
|
1559
|
+
i0.ɵɵelementStart(0, "div", 255)(1, "div", 256)(2, "div", 257)(3, "h4");
|
|
1559
1560
|
i0.ɵɵtext(4, "Run A (Baseline)");
|
|
1560
1561
|
i0.ɵɵelementEnd();
|
|
1561
|
-
i0.ɵɵtemplate(5,
|
|
1562
|
+
i0.ɵɵtemplate(5, TestSuiteFormComponentExtended_div_62_div_5_Template, 2, 1, "div", 258)(6, TestSuiteFormComponentExtended_div_62_div_6_Template, 12, 5, "div", 259);
|
|
1562
1563
|
i0.ɵɵelementEnd();
|
|
1563
|
-
i0.ɵɵelementStart(7, "div",
|
|
1564
|
-
i0.ɵɵelement(8, "i",
|
|
1564
|
+
i0.ɵɵelementStart(7, "div", 260);
|
|
1565
|
+
i0.ɵɵelement(8, "i", 261);
|
|
1565
1566
|
i0.ɵɵelementEnd();
|
|
1566
|
-
i0.ɵɵelementStart(9, "div",
|
|
1567
|
+
i0.ɵɵelementStart(9, "div", 257)(10, "h4");
|
|
1567
1568
|
i0.ɵɵtext(11, "Run B (Compare)");
|
|
1568
1569
|
i0.ɵɵelementEnd();
|
|
1569
|
-
i0.ɵɵtemplate(12,
|
|
1570
|
+
i0.ɵɵtemplate(12, TestSuiteFormComponentExtended_div_62_div_12_Template, 2, 1, "div", 258)(13, TestSuiteFormComponentExtended_div_62_div_13_Template, 12, 5, "div", 259);
|
|
1570
1571
|
i0.ɵɵelementEnd()();
|
|
1571
|
-
i0.ɵɵtemplate(14,
|
|
1572
|
+
i0.ɵɵtemplate(14, TestSuiteFormComponentExtended_div_62_div_14_Template, 46, 24, "div", 262)(15, TestSuiteFormComponentExtended_div_62_div_15_Template, 2, 0, "div", 61)(16, TestSuiteFormComponentExtended_div_62_div_16_Template, 7, 0, "div", 263)(17, TestSuiteFormComponentExtended_div_62_div_17_Template, 10, 0, "div", 63);
|
|
1572
1573
|
i0.ɵɵelementEnd();
|
|
1573
1574
|
} if (rf & 2) {
|
|
1574
1575
|
const ctx_r0 = i0.ɵɵnextContext();
|
|
@@ -1589,37 +1590,37 @@ function TestSuiteFormComponentExtended_div_50_Template(rf, ctx) { if (rf & 1) {
|
|
|
1589
1590
|
i0.ɵɵadvance();
|
|
1590
1591
|
i0.ɵɵproperty("ngIf", ctx_r0.runsLoaded && ctx_r0.suiteRuns.length < 2);
|
|
1591
1592
|
} }
|
|
1592
|
-
function
|
|
1593
|
+
function TestSuiteFormComponentExtended_div_65_Template(rf, ctx) { if (rf & 1) {
|
|
1593
1594
|
const _r39 = i0.ɵɵgetCurrentView();
|
|
1594
|
-
i0.ɵɵelementStart(0, "div",
|
|
1595
|
-
i0.ɵɵelement(2, "i",
|
|
1595
|
+
i0.ɵɵelementStart(0, "div", 313)(1, "div", 314);
|
|
1596
|
+
i0.ɵɵelement(2, "i", 41);
|
|
1596
1597
|
i0.ɵɵtext(3, " Shortcuts ");
|
|
1597
|
-
i0.ɵɵelementStart(4, "button",
|
|
1598
|
-
i0.ɵɵlistener("click", function
|
|
1599
|
-
i0.ɵɵelement(5, "i",
|
|
1598
|
+
i0.ɵɵelementStart(4, "button", 315);
|
|
1599
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_div_65_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r39); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.toggleShortcuts()); });
|
|
1600
|
+
i0.ɵɵelement(5, "i", 195);
|
|
1600
1601
|
i0.ɵɵelementEnd()();
|
|
1601
|
-
i0.ɵɵelementStart(6, "div",
|
|
1602
|
+
i0.ɵɵelementStart(6, "div", 316)(7, "div", 317)(8, "span");
|
|
1602
1603
|
i0.ɵɵtext(9, "Refresh");
|
|
1603
1604
|
i0.ɵɵelementEnd();
|
|
1604
|
-
i0.ɵɵelementStart(10, "span",
|
|
1605
|
+
i0.ɵɵelementStart(10, "span", 318)(11, "kbd");
|
|
1605
1606
|
i0.ɵɵtext(12, "Cmd");
|
|
1606
1607
|
i0.ɵɵelementEnd();
|
|
1607
1608
|
i0.ɵɵelementStart(13, "kbd");
|
|
1608
1609
|
i0.ɵɵtext(14, "R");
|
|
1609
1610
|
i0.ɵɵelementEnd()()();
|
|
1610
|
-
i0.ɵɵelementStart(15, "div",
|
|
1611
|
+
i0.ɵɵelementStart(15, "div", 317)(16, "span");
|
|
1611
1612
|
i0.ɵɵtext(17, "Run Suite");
|
|
1612
1613
|
i0.ɵɵelementEnd();
|
|
1613
|
-
i0.ɵɵelementStart(18, "span",
|
|
1614
|
+
i0.ɵɵelementStart(18, "span", 318)(19, "kbd");
|
|
1614
1615
|
i0.ɵɵtext(20, "Cmd");
|
|
1615
1616
|
i0.ɵɵelementEnd();
|
|
1616
1617
|
i0.ɵɵelementStart(21, "kbd");
|
|
1617
1618
|
i0.ɵɵtext(22, "Enter");
|
|
1618
1619
|
i0.ɵɵelementEnd()()();
|
|
1619
|
-
i0.ɵɵelementStart(23, "div",
|
|
1620
|
+
i0.ɵɵelementStart(23, "div", 317)(24, "span");
|
|
1620
1621
|
i0.ɵɵtext(25, "Switch Tabs");
|
|
1621
1622
|
i0.ɵɵelementEnd();
|
|
1622
|
-
i0.ɵɵelementStart(26, "span",
|
|
1623
|
+
i0.ɵɵelementStart(26, "span", 318)(27, "kbd");
|
|
1623
1624
|
i0.ɵɵtext(28, "1");
|
|
1624
1625
|
i0.ɵɵelementEnd();
|
|
1625
1626
|
i0.ɵɵtext(29, "-");
|
|
@@ -1630,13 +1631,14 @@ function TestSuiteFormComponentExtended_div_53_Template(rf, ctx) { if (rf & 1) {
|
|
|
1630
1631
|
/** Settings key for keyboard shortcuts visibility */
|
|
1631
1632
|
const SHORTCUTS_SETTINGS_KEY = '__mj.Testing.ShowKeyboardShortcuts';
|
|
1632
1633
|
let TestSuiteFormComponentExtended = class TestSuiteFormComponentExtended extends TestSuiteFormComponent {
|
|
1633
|
-
constructor(elementRef, sharedService, router, route, cdr, testingDialogService, evalPrefsService, viewContainerRef) {
|
|
1634
|
+
constructor(elementRef, sharedService, router, route, cdr, testingDialogService, evalPrefsService, viewContainerRef, appManager) {
|
|
1634
1635
|
super(elementRef, sharedService, router, route, cdr);
|
|
1635
1636
|
this.router = router;
|
|
1636
1637
|
this.cdr = cdr;
|
|
1637
1638
|
this.testingDialogService = testingDialogService;
|
|
1638
1639
|
this.evalPrefsService = evalPrefsService;
|
|
1639
1640
|
this.viewContainerRef = viewContainerRef;
|
|
1641
|
+
this.appManager = appManager;
|
|
1640
1642
|
this.destroy$ = new Subject();
|
|
1641
1643
|
// UI state
|
|
1642
1644
|
this.activeTab = 'overview';
|
|
@@ -1885,6 +1887,12 @@ let TestSuiteFormComponentExtended = class TestSuiteFormComponentExtended extend
|
|
|
1885
1887
|
openSuiteRun(runId) {
|
|
1886
1888
|
SharedService.Instance.OpenEntityRecord('MJ: Test Suite Runs', CompositeKey.FromID(runId));
|
|
1887
1889
|
}
|
|
1890
|
+
navigateToTestingDashboard() {
|
|
1891
|
+
const testingApp = this.appManager.GetAppByName('Testing');
|
|
1892
|
+
if (testingApp) {
|
|
1893
|
+
this.navigationService.SwitchToApp(testingApp.ID);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1888
1896
|
async runSuite() {
|
|
1889
1897
|
if (this.record?.ID) {
|
|
1890
1898
|
this.testingDialogService.OpenSuiteDialog(this.record.ID, this.viewContainerRef);
|
|
@@ -3316,7 +3324,7 @@ let TestSuiteFormComponentExtended = class TestSuiteFormComponentExtended extend
|
|
|
3316
3324
|
console.warn('Failed to save shortcuts setting:', error);
|
|
3317
3325
|
}
|
|
3318
3326
|
}
|
|
3319
|
-
static { this.ɵfac = function TestSuiteFormComponentExtended_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestSuiteFormComponentExtended)(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)); }; }
|
|
3327
|
+
static { this.ɵfac = function TestSuiteFormComponentExtended_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TestSuiteFormComponentExtended)(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)); }; }
|
|
3320
3328
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestSuiteFormComponentExtended, selectors: [["mj-test-suite-form"]], viewQuery: function TestSuiteFormComponentExtended_Query(rf, ctx) { if (rf & 1) {
|
|
3321
3329
|
i0.ɵɵviewQuery(_c0, 5);
|
|
3322
3330
|
} if (rf & 2) {
|
|
@@ -3324,76 +3332,89 @@ let TestSuiteFormComponentExtended = class TestSuiteFormComponentExtended extend
|
|
|
3324
3332
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.chartContainer = _t.first);
|
|
3325
3333
|
} }, hostBindings: function TestSuiteFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
|
|
3326
3334
|
i0.ɵɵlistener("keydown", function TestSuiteFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, false, i0.ɵɵresolveDocument);
|
|
3327
|
-
} }, features: [i0.ɵɵInheritDefinitionFeature], decls: 54, vars: 35, consts: [["chartContainer", ""], ["kendoDialogContainer", "", 1, "test-suite-form"], [1, "suite-header"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "fas", "fa-layer-group"], [1, "suite-info"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], ["class", "test-count", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["kendoButton", "", "themeColor", "primary", 3, "click"], [1, "fas", "fa-play"], ["kendoButton", "", 3, "click", "disabled"], ["class", "suite-description", 4, "ngIf"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], ["class", "tab-badge", 4, "ngIf"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "tests-tab", 4, "ngIf"], ["class", "runs-tab", 4, "ngIf"], ["class", "analytics-tab", 4, "ngIf"], ["class", "compare-tab", 4, "ngIf"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], ["class", "keyboard-shortcuts", 4, "ngIf"], [1, "test-count"], [1, "suite-description"], [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, "config-section"], [1, "fas", "fa-cogs"], [1, "config-grid"], [1, "config-item"], ["type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-hint"], [1, "tests-tab"], ["class", "loading-state", 4, "ngIf"], ["class", "tests-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-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "tests-list"], ["class", "test-item", 3, "click", 4, "ngFor", "ngForOf"], [1, "test-item", 3, "click"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content"], [1, "test-name"], [1, "test-status"], [4, "ngIf"], [1, "fas", "fa-chevron-right"], [1, "empty-state"], [1, "empty-icon"], [1, "runs-tab"], ["class", "runs-list", 4, "ngIf"], [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"], [1, "run-eval-metrics"], ["class", "eval-metric status", 3, "class", 4, "ngIf"], ["class", "eval-metric human", "title", "Human evaluation", 4, "ngIf"], ["class", "eval-metric auto", "title", "Auto score (pass rate)", 3, "high", "medium", "low", 4, "ngIf"], ["class", "run-tags", 4, "ngIf"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], ["title", "Human evaluation", 1, "eval-metric", "human"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "run-tags"], ["class", "tag-chip", 4, "ngFor", "ngForOf"], [1, "tag-chip"], [1, "fas", "fa-play-circle"], [1, "analytics-tab"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], [1, "analytics-filters"], [1, "filters-header", 3, "click"], [1, "filters-title"], [1, "fas", "fa-filter"], ["class", "filter-summary", 4, "ngIf"], ["class", "filters-content", 4, "ngIf"], [1, "filter-summary"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], ["class", "filter-group", 4, "ngIf"], ["class", "filter-hint", 4, "ngIf"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], ["class", "filter-btn tag-btn", 3, "active", "click", 4, "ngFor", "ngForOf"], [1, "filter-hint"], [1, "filter-btn", "tag-btn", 3, "click"], ["class", "fas fa-check", 4, "ngIf"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], ["class", "clickable-row", 3, "click", 4, "ngFor", "ngForOf"], ["class", "empty-state small", 4, "ngIf"], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], ["class", "tag-chip-table", 4, "ngFor", "ngForOf"], ["class", "tag-more", 4, "ngIf"], [1, "tag-chip-table"], [1, "tag-more"], [1, "empty-state", "small"], ["class", "matrix-section", 4, "ngIf"], ["text", "Loading test matrix..."], [1, "matrix-section"], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["class", "clear-filter-btn", "title", "Clear filter", 3, "click", 4, "ngIf"], [1, "matrix-run-count"], ["kendoButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], ["class", "run-header", 3, "title", "click", 4, "ngFor", "ngForOf"], [1, "spacer-header"], [3, "row-selected", "click", 4, "ngFor", "ngForOf"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], ["class", "result-cell totals-cell", 4, "ngFor", "ngForOf"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "fas", "fa-times"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], ["class", "run-tags-header", 4, "ngIf"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "run-tags-header"], ["class", "tag-chip-header", 4, "ngFor", "ngForOf"], ["class", "tag-more-header", 4, "ngIf"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], ["class", "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title", "click", 4, "ngFor", "ngForOf"], [1, "result-cell", 3, "click", "ngClass", "title"], ["class", "cell-not-run-indicator", 4, "ngIf"], [1, "cell-eval-stack"], ["class", "cell-status", 3, "ngClass", "cell-skipped-status", "title", 4, "ngIf"], ["class", "cell-human no-feedback", "title", "Human Review: No rating submitted yet", 4, "ngIf"], ["class", "cell-human has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title", 4, "ngIf"], ["class", "cell-auto has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title", 4, "ngIf"], ["class", "cell-auto no-score", "title", "Auto Score: No automated score available", 4, "ngIf"], [1, "cell-status", 3, "ngClass", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-not-run-indicator"], [1, "fas", "fa-minus"], [1, "result-cell", "totals-cell"], [1, "cell-eval-stack", "totals-stack"], ["class", "totals-status", 4, "ngIf"], ["class", "totals-human", 4, "ngIf"], ["class", "totals-auto", 4, "ngIf"], [1, "totals-status"], [1, "pass-count"], [1, "totals-human"], ["class", "avg-label", 4, "ngIf"], [1, "count-label"], [1, "avg-label"], [1, "totals-auto"], ["class", "chart-section", 4, "ngIf"], ["text", "Loading chart data..."], [1, "chart-section"], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], [1, "compare-tab"], [1, "compare-selection"], [1, "compare-run-selector"], ["class", "run-selector-list", 4, "ngIf"], ["class", "selected-run-preview", 4, "ngIf"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], ["class", "compare-results", 4, "ngIf"], ["class", "compare-empty", 4, "ngIf"], [1, "run-selector-list"], ["class", "run-selector-item", 3, "selected", "click", 4, "ngFor", "ngForOf"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], ["class", "selector-tags", 4, "ngIf"], [1, "selector-tags"], ["class", "tag-mini", 4, "ngFor", "ngForOf"], [1, "tag-mini"], [1, "selected-run-preview"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], ["class", "run-selector-item", 3, "selected", "disabled", "click", 4, "ngFor", "ngForOf"], [1, "compare-results"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass", 4, "ngFor", "ngForOf"], [3, "ngClass"], ["class", "status-chip", 3, "ngClass", 4, "ngIf"], ["class", "status-chip status-missing", 4, "ngIf"], [3, "ngClass", 4, "ngIf"], ["class", "muted", 4, "ngIf"], ["class", "change-indicator improved", 4, "ngIf"], ["class", "change-indicator regressed", 4, "ngIf"], ["class", "change-indicator unchanged", 4, "ngIf"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "fas", "fa-arrow-up"], [1, "change-indicator", "regressed"], [1, "fas", "fa-arrow-down"], [1, "change-indicator", "unchanged"], ["text", "Loading comparison data..."], [1, "compare-empty"], [1, "compare-empty-icon"], [1, "keyboard-shortcuts"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"]], template: function TestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
3328
|
-
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "
|
|
3329
|
-
i0.ɵɵ
|
|
3335
|
+
} }, features: [i0.ɵɵInheritDefinitionFeature], decls: 66, vars: 36, consts: [["chartContainer", ""], ["kendoDialogContainer", "", 1, "test-suite-form"], [1, "suite-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-layer-group"], [1, "header-content"], [1, "header-left"], [1, "suite-icon"], [1, "suite-info"], [1, "suite-meta"], [1, "status-badge", 3, "ngClass"], [1, "fas", 3, "ngClass"], ["class", "test-count", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "title", "Export to CSV", 3, "click"], [1, "fas", "fa-file-excel"], ["kendoButton", "", "themeColor", "primary", 3, "click"], [1, "fas", "fa-play"], ["kendoButton", "", 3, "click", "disabled"], ["class", "suite-description", 4, "ngIf"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-flask"], ["class", "tab-badge", 4, "ngIf"], [1, "fas", "fa-history"], [1, "fas", "fa-chart-line"], [1, "fas", "fa-balance-scale"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "tests-tab", 4, "ngIf"], ["class", "runs-tab", 4, "ngIf"], ["class", "analytics-tab", 4, "ngIf"], ["class", "compare-tab", 4, "ngIf"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], ["class", "keyboard-shortcuts", 4, "ngIf"], [1, "test-count"], [1, "suite-description"], [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, "config-section"], [1, "fas", "fa-cogs"], [1, "config-grid"], [1, "config-item"], ["type", "number", "placeholder", "Default: 300000 (5 min)", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-hint"], [1, "tests-tab"], ["class", "loading-state", 4, "ngIf"], ["class", "tests-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-sequence"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "tests-list"], ["class", "test-item", 3, "click", 4, "ngFor", "ngForOf"], [1, "test-item", 3, "click"], [1, "test-sequence"], [1, "test-icon"], [1, "test-content"], [1, "test-name"], [1, "test-status"], [4, "ngIf"], [1, "fas", "fa-chevron-right"], [1, "empty-state"], [1, "empty-icon"], [1, "runs-tab"], ["class", "runs-list", 4, "ngIf"], [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"], [1, "run-eval-metrics"], ["class", "eval-metric status", 3, "class", 4, "ngIf"], ["class", "eval-metric human", "title", "Human evaluation", 4, "ngIf"], ["class", "eval-metric auto", "title", "Auto score (pass rate)", 3, "high", "medium", "low", 4, "ngIf"], ["class", "run-tags", 4, "ngIf"], [1, "fas", "fa-check-circle"], [1, "eval-metric", "status"], ["title", "Human evaluation", 1, "eval-metric", "human"], [1, "fas", "fa-user"], [1, "eval-pending"], [1, "fas", "fa-clock"], ["title", "Auto score (pass rate)", 1, "eval-metric", "auto"], [1, "fas", "fa-robot"], [1, "run-tags"], ["class", "tag-chip", 4, "ngFor", "ngForOf"], [1, "tag-chip"], [1, "fas", "fa-play-circle"], [1, "analytics-tab"], ["text", "Loading analytics data..."], [1, "analytics-subnav"], [1, "subnav-tabs"], [1, "subnav-tab", 3, "click"], [1, "fas", "fa-chart-bar"], [1, "fas", "fa-th"], [1, "fas", "fa-project-diagram"], [1, "analytics-filters"], [1, "filters-header", 3, "click"], [1, "filters-title"], [1, "fas", "fa-filter"], ["class", "filter-summary", 4, "ngIf"], ["class", "filters-content", 4, "ngIf"], [1, "filter-summary"], [1, "filters-content"], [1, "filter-group"], [1, "filter-buttons"], [1, "filter-btn", 3, "click"], ["class", "filter-group", 4, "ngIf"], ["class", "filter-hint", 4, "ngIf"], [1, "filter-buttons", "tag-filters"], [1, "filter-btn", "tag-btn", "all-tags-btn", 3, "click"], ["class", "filter-btn tag-btn", 3, "active", "click", 4, "ngFor", "ngForOf"], [1, "filter-hint"], [1, "filter-btn", "tag-btn", 3, "click"], ["class", "fas fa-check", 4, "ngIf"], [1, "fas", "fa-check"], [1, "analytics-kpis"], [1, "kpi-card"], [1, "kpi-icon"], [1, "kpi-content"], [1, "kpi-value"], [1, "kpi-label"], [1, "kpi-icon", "success"], [1, "kpi-trend", 3, "ngClass"], [1, "kpi-icon", "info"], [1, "kpi-icon", "warning"], [1, "fas", "fa-dollar-sign"], [1, "analytics-table-section"], [1, "fas", "fa-table"], [1, "analytics-table-wrapper"], [1, "analytics-table"], ["class", "clickable-row", 3, "click", 4, "ngFor", "ngForOf"], ["class", "empty-state small", 4, "ngIf"], [1, "clickable-row", 3, "click"], [1, "status-chip", 3, "ngClass"], [1, "pass-rate-cell"], [1, "pass-rate-bar", 3, "ngClass"], [1, "tag-cell"], ["class", "tag-chip-table", 4, "ngFor", "ngForOf"], ["class", "tag-more", 4, "ngIf"], [1, "tag-chip-table"], [1, "tag-more"], [1, "empty-state", "small"], ["class", "matrix-section", 4, "ngIf"], ["text", "Loading test matrix..."], [1, "matrix-section"], [1, "matrix-header"], [1, "matrix-header-right"], [1, "matrix-filter-input"], [1, "fas", "fa-search"], ["type", "text", "placeholder", "Filter tests...", 1, "filter-input", 3, "input", "value"], ["class", "clear-filter-btn", "title", "Clear filter", 3, "click", 4, "ngIf"], [1, "matrix-run-count"], ["kendoButton", "", "title", "Export matrix to CSV", 3, "click", "disabled"], [1, "fas", "fa-download"], [1, "matrix-scroll-container"], [1, "test-matrix"], ["title", "Sort by sequence", 1, "seq-header", 3, "click"], ["title", "Sort by name", 1, "test-name-header", 3, "click"], ["class", "run-header", 3, "title", "click", 4, "ngFor", "ngForOf"], [1, "spacer-header"], [3, "row-selected", "click", 4, "ngFor", "ngForOf"], [1, "totals-row"], [1, "seq-cell", "totals-label"], [1, "test-name-cell", "totals-label"], ["class", "result-cell totals-cell", 4, "ngFor", "ngForOf"], [1, "spacer-cell"], ["title", "Clear filter", 1, "clear-filter-btn", 3, "click"], [1, "fas", "fa-times"], [1, "run-header", 3, "click", "title"], [1, "run-header-content"], ["class", "run-tags-header", 4, "ngIf"], [1, "run-date"], [1, "run-pass-rate", 3, "ngClass"], [1, "run-tags-header"], ["class", "tag-chip-header", 4, "ngFor", "ngForOf"], ["class", "tag-more-header", 4, "ngIf"], [1, "tag-chip-header"], [1, "tag-more-header"], [3, "click"], [1, "seq-cell"], [1, "test-name-cell"], [1, "test-name", 3, "title"], ["class", "result-cell", 3, "ngClass", "clickable", "cell-not-run", "title", "click", 4, "ngFor", "ngForOf"], [1, "result-cell", 3, "click", "ngClass", "title"], ["class", "cell-not-run-indicator", 4, "ngIf"], [1, "cell-eval-stack"], ["class", "cell-status", 3, "ngClass", "cell-skipped-status", "title", 4, "ngIf"], ["class", "cell-human no-feedback", "title", "Human Review: No rating submitted yet", 4, "ngIf"], ["class", "cell-human has-feedback", 3, "rating-low", "rating-medium", "rating-good", "rating-excellent", "title", 4, "ngIf"], ["class", "cell-auto has-score", 3, "score-low", "score-medium", "score-good", "score-excellent", "title", 4, "ngIf"], ["class", "cell-auto no-score", "title", "Auto Score: No automated score available", 4, "ngIf"], [1, "cell-status", 3, "ngClass", "title"], ["title", "Human Review: No rating submitted yet", 1, "cell-human", "no-feedback"], [1, "fas", "fa-user-slash"], [1, "cell-human", "has-feedback", 3, "title"], [1, "rating-value"], [1, "cell-auto", "has-score", 3, "title"], [1, "score-value"], ["title", "Auto Score: No automated score available", 1, "cell-auto", "no-score"], [1, "cell-not-run-indicator"], [1, "fas", "fa-minus"], [1, "result-cell", "totals-cell"], [1, "cell-eval-stack", "totals-stack"], ["class", "totals-status", 4, "ngIf"], ["class", "totals-human", 4, "ngIf"], ["class", "totals-auto", 4, "ngIf"], [1, "totals-status"], [1, "pass-count"], [1, "totals-human"], ["class", "avg-label", 4, "ngIf"], [1, "count-label"], [1, "avg-label"], [1, "totals-auto"], ["class", "chart-section", 4, "ngIf"], ["text", "Loading chart data..."], [1, "chart-section"], [1, "chart-header"], [1, "chart-legend"], [1, "legend-item", "chart-passed"], [1, "legend-item", "chart-failed"], [1, "legend-item", "chart-error"], [1, "fas", "fa-exclamation"], [1, "legend-item", "chart-skipped"], [1, "fas", "fa-forward"], [1, "chart-container"], [1, "d3-chart"], [1, "chart-info"], [1, "compare-tab"], [1, "compare-selection"], [1, "compare-run-selector"], ["class", "run-selector-list", 4, "ngIf"], ["class", "selected-run-preview", 4, "ngIf"], [1, "compare-vs"], [1, "fas", "fa-exchange-alt"], ["class", "compare-results", 4, "ngIf"], ["class", "compare-empty", 4, "ngIf"], [1, "run-selector-list"], ["class", "run-selector-item", 3, "selected", "click", 4, "ngFor", "ngForOf"], [1, "run-selector-item", 3, "click"], [1, "selector-status"], [1, "selector-content"], [1, "selector-date"], [1, "selector-rate"], ["class", "selector-tags", 4, "ngIf"], [1, "selector-tags"], ["class", "tag-mini", 4, "ngFor", "ngForOf"], [1, "tag-mini"], [1, "selected-run-preview"], [1, "preview-header"], [1, "preview-label"], [1, "clear-btn", 3, "click"], [1, "preview-details"], [1, "preview-rate"], ["class", "run-selector-item", 3, "selected", "disabled", "click", 4, "ngFor", "ngForOf"], [1, "compare-results"], [1, "compare-summary"], [1, "compare-summary-card"], [1, "summary-label"], [1, "summary-value", 3, "ngClass"], [1, "compare-summary-card", "improved"], [1, "summary-value"], [1, "compare-summary-card", "regressed"], [1, "compare-table-section"], [1, "fas", "fa-list"], [1, "compare-table-wrapper"], [1, "compare-table"], [3, "ngClass", 4, "ngFor", "ngForOf"], [3, "ngClass"], ["class", "status-chip", 3, "ngClass", 4, "ngIf"], ["class", "status-chip status-missing", 4, "ngIf"], [3, "ngClass", 4, "ngIf"], ["class", "muted", 4, "ngIf"], ["class", "change-indicator improved", 4, "ngIf"], ["class", "change-indicator regressed", 4, "ngIf"], ["class", "change-indicator unchanged", 4, "ngIf"], [1, "status-chip", "status-missing"], [1, "muted"], [1, "change-indicator", "improved"], [1, "fas", "fa-arrow-up"], [1, "change-indicator", "regressed"], [1, "fas", "fa-arrow-down"], [1, "change-indicator", "unchanged"], ["text", "Loading comparison data..."], [1, "compare-empty"], [1, "compare-empty-icon"], [1, "keyboard-shortcuts"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"]], template: function TestSuiteFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
3336
|
+
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "nav", 3)(3, "ol")(4, "li")(5, "a", 4);
|
|
3337
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
|
|
3338
|
+
i0.ɵɵelement(6, "i", 5);
|
|
3339
|
+
i0.ɵɵelementStart(7, "span", 6);
|
|
3340
|
+
i0.ɵɵtext(8, "Testing");
|
|
3341
|
+
i0.ɵɵelementEnd()()();
|
|
3342
|
+
i0.ɵɵelementStart(9, "li", 7);
|
|
3343
|
+
i0.ɵɵelement(10, "i", 8)(11, "i", 9);
|
|
3344
|
+
i0.ɵɵelementStart(12, "span");
|
|
3345
|
+
i0.ɵɵtext(13);
|
|
3346
|
+
i0.ɵɵelementEnd()()()();
|
|
3347
|
+
i0.ɵɵelementStart(14, "div", 10)(15, "div", 11)(16, "div", 12);
|
|
3348
|
+
i0.ɵɵelement(17, "i", 9);
|
|
3330
3349
|
i0.ɵɵelementEnd();
|
|
3331
|
-
i0.ɵɵelementStart(
|
|
3332
|
-
i0.ɵɵtext(
|
|
3350
|
+
i0.ɵɵelementStart(18, "div", 13)(19, "h1");
|
|
3351
|
+
i0.ɵɵtext(20);
|
|
3333
3352
|
i0.ɵɵelementEnd();
|
|
3334
|
-
i0.ɵɵelementStart(
|
|
3335
|
-
i0.ɵɵelement(
|
|
3336
|
-
i0.ɵɵtext(
|
|
3353
|
+
i0.ɵɵelementStart(21, "div", 14)(22, "span", 15);
|
|
3354
|
+
i0.ɵɵelement(23, "i", 16);
|
|
3355
|
+
i0.ɵɵtext(24);
|
|
3337
3356
|
i0.ɵɵelementEnd();
|
|
3338
|
-
i0.ɵɵtemplate(
|
|
3357
|
+
i0.ɵɵtemplate(25, TestSuiteFormComponentExtended_span_25_Template, 3, 1, "span", 17);
|
|
3339
3358
|
i0.ɵɵelementEnd()()();
|
|
3340
|
-
i0.ɵɵelementStart(
|
|
3341
|
-
i0.ɵɵelement(
|
|
3342
|
-
i0.ɵɵelementStart(
|
|
3343
|
-
i0.ɵɵlistener("click", function
|
|
3344
|
-
i0.ɵɵelement(
|
|
3345
|
-
i0.ɵɵtext(
|
|
3359
|
+
i0.ɵɵelementStart(26, "div", 18);
|
|
3360
|
+
i0.ɵɵelement(27, "app-evaluation-mode-toggle");
|
|
3361
|
+
i0.ɵɵelementStart(28, "button", 19);
|
|
3362
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_28_listener() { return ctx.exportToExcel(); });
|
|
3363
|
+
i0.ɵɵelement(29, "i", 20);
|
|
3364
|
+
i0.ɵɵtext(30, " Export ");
|
|
3346
3365
|
i0.ɵɵelementEnd();
|
|
3347
|
-
i0.ɵɵelementStart(
|
|
3348
|
-
i0.ɵɵlistener("click", function
|
|
3349
|
-
i0.ɵɵelement(
|
|
3350
|
-
i0.ɵɵtext(
|
|
3366
|
+
i0.ɵɵelementStart(31, "button", 21);
|
|
3367
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_31_listener() { return ctx.runSuite(); });
|
|
3368
|
+
i0.ɵɵelement(32, "i", 22);
|
|
3369
|
+
i0.ɵɵtext(33, " Run Suite ");
|
|
3351
3370
|
i0.ɵɵelementEnd();
|
|
3352
|
-
i0.ɵɵelementStart(
|
|
3353
|
-
i0.ɵɵlistener("click", function
|
|
3354
|
-
i0.ɵɵelement(
|
|
3355
|
-
i0.ɵɵtext(
|
|
3371
|
+
i0.ɵɵelementStart(34, "button", 23);
|
|
3372
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_34_listener() { return ctx.refresh(); });
|
|
3373
|
+
i0.ɵɵelement(35, "i", 16);
|
|
3374
|
+
i0.ɵɵtext(36);
|
|
3356
3375
|
i0.ɵɵelementEnd()()();
|
|
3357
|
-
i0.ɵɵtemplate(
|
|
3376
|
+
i0.ɵɵtemplate(37, TestSuiteFormComponentExtended_div_37_Template, 3, 1, "div", 24);
|
|
3358
3377
|
i0.ɵɵelementEnd();
|
|
3359
|
-
i0.ɵɵelementStart(
|
|
3360
|
-
i0.ɵɵlistener("click", function
|
|
3361
|
-
i0.ɵɵelement(
|
|
3362
|
-
i0.ɵɵtext(
|
|
3378
|
+
i0.ɵɵelementStart(38, "div", 25)(39, "div", 26)(40, "button", 27);
|
|
3379
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_40_listener() { return ctx.changeTab("overview"); });
|
|
3380
|
+
i0.ɵɵelement(41, "i", 28);
|
|
3381
|
+
i0.ɵɵtext(42, " Overview ");
|
|
3363
3382
|
i0.ɵɵelementEnd();
|
|
3364
|
-
i0.ɵɵelementStart(
|
|
3365
|
-
i0.ɵɵlistener("click", function
|
|
3366
|
-
i0.ɵɵelement(
|
|
3367
|
-
i0.ɵɵtext(
|
|
3368
|
-
i0.ɵɵtemplate(
|
|
3383
|
+
i0.ɵɵelementStart(43, "button", 27);
|
|
3384
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_43_listener() { return ctx.changeTab("tests"); });
|
|
3385
|
+
i0.ɵɵelement(44, "i", 29);
|
|
3386
|
+
i0.ɵɵtext(45, " Tests ");
|
|
3387
|
+
i0.ɵɵtemplate(46, TestSuiteFormComponentExtended_span_46_Template, 2, 1, "span", 30);
|
|
3369
3388
|
i0.ɵɵelementEnd();
|
|
3370
|
-
i0.ɵɵelementStart(
|
|
3371
|
-
i0.ɵɵlistener("click", function
|
|
3372
|
-
i0.ɵɵelement(
|
|
3373
|
-
i0.ɵɵtext(
|
|
3374
|
-
i0.ɵɵtemplate(
|
|
3389
|
+
i0.ɵɵelementStart(47, "button", 27);
|
|
3390
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_47_listener() { return ctx.changeTab("runs"); });
|
|
3391
|
+
i0.ɵɵelement(48, "i", 31);
|
|
3392
|
+
i0.ɵɵtext(49, " Runs ");
|
|
3393
|
+
i0.ɵɵtemplate(50, TestSuiteFormComponentExtended_span_50_Template, 2, 1, "span", 30);
|
|
3375
3394
|
i0.ɵɵelementEnd();
|
|
3376
|
-
i0.ɵɵelementStart(
|
|
3377
|
-
i0.ɵɵlistener("click", function
|
|
3378
|
-
i0.ɵɵelement(
|
|
3379
|
-
i0.ɵɵtext(
|
|
3395
|
+
i0.ɵɵelementStart(51, "button", 27);
|
|
3396
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_51_listener() { return ctx.changeTab("analytics"); });
|
|
3397
|
+
i0.ɵɵelement(52, "i", 32);
|
|
3398
|
+
i0.ɵɵtext(53, " Analytics ");
|
|
3380
3399
|
i0.ɵɵelementEnd();
|
|
3381
|
-
i0.ɵɵelementStart(
|
|
3382
|
-
i0.ɵɵlistener("click", function
|
|
3383
|
-
i0.ɵɵelement(
|
|
3384
|
-
i0.ɵɵtext(
|
|
3400
|
+
i0.ɵɵelementStart(54, "button", 27);
|
|
3401
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_54_listener() { return ctx.changeTab("compare"); });
|
|
3402
|
+
i0.ɵɵelement(55, "i", 33);
|
|
3403
|
+
i0.ɵɵtext(56, " Compare ");
|
|
3385
3404
|
i0.ɵɵelementEnd()()();
|
|
3386
|
-
i0.ɵɵelementStart(
|
|
3387
|
-
i0.ɵɵtemplate(
|
|
3405
|
+
i0.ɵɵelementStart(57, "div", 34);
|
|
3406
|
+
i0.ɵɵtemplate(58, TestSuiteFormComponentExtended_div_58_Template, 45, 13, "div", 35)(59, TestSuiteFormComponentExtended_div_59_Template, 4, 3, "div", 36)(60, TestSuiteFormComponentExtended_div_60_Template, 4, 3, "div", 37)(61, TestSuiteFormComponentExtended_div_61_Template, 4, 3, "div", 38)(62, TestSuiteFormComponentExtended_div_62_Template, 18, 8, "div", 39);
|
|
3388
3407
|
i0.ɵɵelementEnd();
|
|
3389
|
-
i0.ɵɵelementStart(
|
|
3390
|
-
i0.ɵɵlistener("click", function
|
|
3391
|
-
i0.ɵɵelement(
|
|
3408
|
+
i0.ɵɵelementStart(63, "button", 40);
|
|
3409
|
+
i0.ɵɵlistener("click", function TestSuiteFormComponentExtended_Template_button_click_63_listener() { return ctx.toggleShortcuts(); });
|
|
3410
|
+
i0.ɵɵelement(64, "i", 41);
|
|
3392
3411
|
i0.ɵɵelementEnd();
|
|
3393
|
-
i0.ɵɵtemplate(
|
|
3412
|
+
i0.ɵɵtemplate(65, TestSuiteFormComponentExtended_div_65_Template, 32, 0, "div", 42);
|
|
3394
3413
|
i0.ɵɵelementEnd();
|
|
3395
3414
|
} if (rf & 2) {
|
|
3396
|
-
i0.ɵɵadvance(
|
|
3415
|
+
i0.ɵɵadvance(13);
|
|
3416
|
+
i0.ɵɵtextInterpolate(ctx.record.Name);
|
|
3417
|
+
i0.ɵɵadvance(3);
|
|
3397
3418
|
i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
|
|
3398
3419
|
i0.ɵɵadvance(4);
|
|
3399
3420
|
i0.ɵɵtextInterpolate(ctx.record.Name);
|
|
@@ -3446,7 +3467,7 @@ let TestSuiteFormComponentExtended = class TestSuiteFormComponentExtended extend
|
|
|
3446
3467
|
i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
|
|
3447
3468
|
i0.ɵɵadvance(2);
|
|
3448
3469
|
i0.ɵɵproperty("ngIf", ctx.showShortcuts);
|
|
3449
|
-
} }, dependencies: [i4.NgClass, i4.NgForOf, i4.NgIf, i5.DefaultValueAccessor, i5.NumberValueAccessor, i5.NgControlStatus, i5.NgModel, i6.DialogContainerDirective, i7.ButtonComponent, i3.EvaluationModeToggleComponent, i8.LoadingComponent, i4.DatePipe], styles: ["\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-success: #10b981;\n --test-error: #ef4444;\n --test-warning: #f59e0b;\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);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-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, sans-serif;\n}\n\n\n\n.suite-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.suite-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.suite-icon[_ngcontent-%COMP%]:hover { transform: scale(1.05); }\n\n.suite-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.suite-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 word-wrap: break-word;\n}\n\n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\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 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-count[_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.suite-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-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.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 scrollbar-width: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar { display: none; }\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-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}\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}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n 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.info-section[_ngcontent-%COMP%], .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.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .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.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%], .config-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 font-weight: 500;\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 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[_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}\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-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n\n\n.tests-tab[_ngcontent-%COMP%], .runs-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.loading-state[_ngcontent-%COMP%] { padding: 0; }\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-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 50%;\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-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-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.tests-list[_ngcontent-%COMP%], .runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item[_ngcontent-%COMP%], .run-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.test-item[_ngcontent-%COMP%]:hover, .run-item[_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.test-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon[_ngcontent-%COMP%], .run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\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.test-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--test-primary) 0%, #1d4ed8 100%);\n}\n\n.test-content[_ngcontent-%COMP%], .run-content[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.test-name[_ngcontent-%COMP%], .run-header[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id[_ngcontent-%COMP%] { font-weight: 600; }\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\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\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 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 color: var(--test-text-secondary);\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-size: 11px;\n color: var(--test-text);\n}\n\n\n\n@media (max-width: 1024px) {\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header[_ngcontent-%COMP%] { padding: 16px; }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { flex: 1; }\n\n .tab-shortcut[_ngcontent-%COMP%] { display: none; }\n\n .info-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 16px; }\n\n .tab-badge[_ngcontent-%COMP%] { display: none; }\n\n .test-sequence[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item[_ngcontent-%COMP%]:active, .run-item[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%] { min-height: 48px; }\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], *[_ngcontent-%COMP%]::before, *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions[_ngcontent-%COMP%], .tabs-container[_ngcontent-%COMP%], .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n\n\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border: 1px solid #bfdbfe;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: #1d4ed8;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: #f1f5f9;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: #64748b;\n}\n\n.tag-more[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #94a3b8;\n font-weight: 500;\n}\n\n\n\n.run-eval-metrics[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-metric.status.status-completed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #166534;\n}\n\n.eval-metric.status.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.eval-metric.status.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.eval-metric.status.status-pending[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.eval-metric.human[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #f59e0b;\n color: #92400e;\n}\n\n.eval-metric.human[_ngcontent-%COMP%] .eval-pending[_ngcontent-%COMP%] {\n font-size: 9px;\n color: #d97706;\n}\n\n.eval-metric.auto[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n}\n\n.eval-metric.auto.high[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);\n border: 1px solid #86efac;\n color: #166534;\n}\n\n.eval-metric.auto.medium[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #fcd34d;\n color: #92400e;\n}\n\n.eval-metric.auto.low[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n border: 1px solid #fca5a5;\n color: #991b1b;\n}\n\n.tag-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n\n.analytics-filters[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.filters-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header[_ngcontent-%COMP%]:hover {\n background: var(--test-bg);\n}\n\n.filters-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group[_ngcontent-%COMP%] 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.filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\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);\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 border-color: var(--test-primary);\n color: white;\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.filter-hint[_ngcontent-%COMP%] {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters[_ngcontent-%COMP%] {\n max-height: 120px;\n overflow-y: auto;\n}\n\n\n\n.analytics-kpis[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\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: #eff6ff;\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-icon.info[_ngcontent-%COMP%] {\n background: #f0f9ff;\n color: #0ea5e9;\n}\n\n.kpi-icon.warning[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: #f1f5f9;\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n\n\n.analytics-table-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.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed[_ngcontent-%COMP%] { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-passed[_ngcontent-%COMP%] { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-failed[_ngcontent-%COMP%] { background: #fef2f2; color: var(--test-error); }\n.status-chip.status-error[_ngcontent-%COMP%] { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-running[_ngcontent-%COMP%] { background: #eff6ff; color: var(--test-primary); }\n.status-chip.status-pending[_ngcontent-%COMP%] { background: #f5f3ff; color: #8b5cf6; }\n.status-chip.status-cancelled[_ngcontent-%COMP%] { background: #f1f5f9; color: var(--test-disabled); }\n.status-chip.status-missing[_ngcontent-%COMP%] { background: #f1f5f9; color: var(--test-text-muted); }\n.status-chip.status-timeout[_ngcontent-%COMP%] { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-skipped[_ngcontent-%COMP%] { background: #f1f5f9; color: var(--test-disabled); }\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium[_ngcontent-%COMP%] { background: var(--test-warning); }\n.pass-rate-bar.low[_ngcontent-%COMP%] { background: var(--test-error); }\n\n\n\n.analytics-subnav[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\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.subnav-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.subnav-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.matrix-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.matrix-run-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n\n\n.matrix-filter-input[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n background: #f8fafc;\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] i.fa-search[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]::placeholder {\n color: #94a3b8;\n}\n\n.clear-filter-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: #94a3b8;\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn[_ngcontent-%COMP%]:hover {\n background: #e2e8f0;\n color: #64748b;\n}\n\n\n\n.matrix-scroll-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix[_ngcontent-%COMP%] {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n display: table-header-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] {\n display: table-row-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: rgba(59, 130, 246, 0.05);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n border-top: 1px solid rgba(59, 130, 246, 0.3);\n border-bottom: 1px solid rgba(59, 130, 246, 0.3);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n display: table-footer-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid #475569 !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: #64748b;\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; \n\n top: 0;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%] {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .spacer-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.run-pass-rate.medium[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.run-pass-rate.low[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n background: #eff6ff;\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.run-tags-header[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name[_ngcontent-%COMP%] {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell[_ngcontent-%COMP%] {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.result-cell.clickable[_ngcontent-%COMP%]:hover {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n z-index: 5;\n}\n\n.result-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.result-cell.cell-passed[_ngcontent-%COMP%], \n.result-cell.cell-failed[_ngcontent-%COMP%], \n.result-cell.cell-error[_ngcontent-%COMP%], \n.result-cell.cell-timeout[_ngcontent-%COMP%], \n.result-cell.cell-running[_ngcontent-%COMP%], \n.result-cell.cell-pending[_ngcontent-%COMP%] {\n background: #ffffff;\n color: var(--test-text);\n}\n\n\n\n.result-cell.cell-skipped[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none[_ngcontent-%COMP%] {\n background: #f8fafc;\n color: var(--test-text-muted);\n}\n\n.cell-score[_ngcontent-%COMP%] {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n\n\n.cell-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval[_ngcontent-%COMP%] {\n min-width: 120px;\n width: auto;\n}\n\n\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: #f3e8ff;\n color: #7c3aed;\n}\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: #fef3c7;\n color: #d97706;\n font-size: 10px;\n}\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-auto.high[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-auto.medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-auto.low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-none-indicator[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.chart-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.chart-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-passed[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-failed[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-error[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-skipped[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: var(--test-disabled);\n}\n\n.chart-container[_ngcontent-%COMP%] {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: linear-gradient(135deg, #fafbff 0%, #f8fafc 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n.d3-chart[_ngcontent-%COMP%] .node-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%] {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%]:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip[_ngcontent-%COMP%] {\n position: absolute;\n padding: 10px 14px;\n background: rgba(30, 41, 59, 0.95);\n color: white;\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n max-width: 250px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-title[_ngcontent-%COMP%] {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-value[_ngcontent-%COMP%] {\n opacity: 0.8;\n}\n\n.chart-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.compare-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-selection[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list[_ngcontent-%COMP%] {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-selector-item.selected[_ngcontent-%COMP%] {\n border-color: var(--test-primary);\n background: #eff6ff;\n}\n\n.run-selector-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview[_ngcontent-%COMP%] {\n padding: 12px;\n background: #f8fafc;\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.preview-details[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n\n\n.compare-results[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.compare-summary-card.improved[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-success); }\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-error); }\n\n\n\n.compare-table-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.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.compare-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.improved[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.05);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.regressed[_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.05);\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n.muted[_ngcontent-%COMP%] { color: var(--test-text-muted); }\n\n.change-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.change-indicator.regressed[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.change-indicator.unchanged[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: var(--test-text-muted);\n}\n\n\n\n.compare-empty[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-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: 0 auto 20px;\n}\n\n.compare-empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty[_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.compare-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n\n\n.empty-state.small[_ngcontent-%COMP%] {\n padding: 32px 16px;\n}\n\n.empty-state.small[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .compare-selection[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs[_ngcontent-%COMP%] {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .filter-btn[_ngcontent-%COMP%] {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .kpi-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .kpi-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper[_ngcontent-%COMP%], \n .compare-table-wrapper[_ngcontent-%COMP%] {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list[_ngcontent-%COMP%] {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n\n\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] .rating-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 11px;\n}\n\n\n\n.cell-human.rating-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-human.rating-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-human.rating-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-human.rating-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] .score-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 10px;\n}\n\n\n\n.cell-auto.score-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-auto.score-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-auto.score-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-auto.score-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%], \n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #2563eb;\n}\n\n\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: #94a3b8;\n}\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] .cell-eval-stack[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: #94a3b8;\n font-size: 11px;\n}\n\n\n\n\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row[_ngcontent-%COMP%] {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-label[_ngcontent-%COMP%] {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-cell[_ngcontent-%COMP%] {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n}\n\n.totals-stack[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status[_ngcontent-%COMP%], \n.totals-human[_ngcontent-%COMP%], \n.totals-auto[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status[_ngcontent-%COMP%] {\n background: #e0f2fe;\n color: #0369a1;\n}\n\n.totals-status[_ngcontent-%COMP%] .pass-count[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.totals-human[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #1e40af;\n}\n\n.totals-auto[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-auto[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}"], changeDetection: 0 }); }
|
|
3470
|
+
} }, dependencies: [i5.NgClass, i5.NgForOf, i5.NgIf, i6.DefaultValueAccessor, i6.NumberValueAccessor, i6.NgControlStatus, i6.NgModel, i7.DialogContainerDirective, i8.ButtonComponent, i3.EvaluationModeToggleComponent, i9.LoadingComponent, i5.DatePipe], styles: ["\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-success: #10b981;\n --test-error: #ef4444;\n --test-warning: #f59e0b;\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);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-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, sans-serif;\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.suite-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.suite-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.suite-icon[_ngcontent-%COMP%]:hover { transform: scale(1.05); }\n\n.suite-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.suite-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 word-wrap: break-word;\n}\n\n.suite-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\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 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-count[_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.suite-description[_ngcontent-%COMP%] {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-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.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 scrollbar-width: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar { display: none; }\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-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}\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}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n 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.info-section[_ngcontent-%COMP%], .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.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%], .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.info-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%], .config-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 font-weight: 500;\n}\n\n.config-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 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[_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}\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-hint[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n\n\n.tests-tab[_ngcontent-%COMP%], .runs-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.loading-state[_ngcontent-%COMP%] { padding: 0; }\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-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border-radius: 50%;\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-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-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.tests-list[_ngcontent-%COMP%], .runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item[_ngcontent-%COMP%], .run-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.test-item[_ngcontent-%COMP%]:hover, .run-item[_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.test-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon[_ngcontent-%COMP%], .run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\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.test-icon[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--test-primary) 0%, #1d4ed8 100%);\n}\n\n.test-content[_ngcontent-%COMP%], .run-content[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n\n.test-name[_ngcontent-%COMP%], .run-header[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id[_ngcontent-%COMP%] { font-weight: 600; }\n\n.run-status[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status[_ngcontent-%COMP%] span[_ngcontent-%COMP%], .run-meta[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\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\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 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 color: var(--test-text-secondary);\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-size: 11px;\n color: var(--test-text);\n}\n\n\n\n@media (max-width: 1024px) {\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header[_ngcontent-%COMP%] { padding: 16px; }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] { flex: 1; }\n\n .tab-shortcut[_ngcontent-%COMP%] { display: none; }\n\n .info-grid[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\n\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] { font-size: 16px; }\n\n .tab-badge[_ngcontent-%COMP%] { display: none; }\n\n .test-sequence[_ngcontent-%COMP%] { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item[_ngcontent-%COMP%]:active, .run-item[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%] { min-height: 48px; }\n .test-item[_ngcontent-%COMP%], .run-item[_ngcontent-%COMP%] { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], *[_ngcontent-%COMP%]::before, *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions[_ngcontent-%COMP%], .tabs-container[_ngcontent-%COMP%], .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n\n\n\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border: 1px solid #bfdbfe;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: #1d4ed8;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: #f1f5f9;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: #64748b;\n}\n\n.tag-more[_ngcontent-%COMP%] {\n font-size: 10px;\n color: #94a3b8;\n font-weight: 500;\n}\n\n\n\n.run-eval-metrics[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-metric.status.status-completed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #166534;\n}\n\n.eval-metric.status.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.eval-metric.status.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.eval-metric.status.status-pending[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.eval-metric.human[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #f59e0b;\n color: #92400e;\n}\n\n.eval-metric.human[_ngcontent-%COMP%] .eval-pending[_ngcontent-%COMP%] {\n font-size: 9px;\n color: #d97706;\n}\n\n.eval-metric.auto[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n}\n\n.eval-metric.auto.high[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);\n border: 1px solid #86efac;\n color: #166534;\n}\n\n.eval-metric.auto.medium[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #fcd34d;\n color: #92400e;\n}\n\n.eval-metric.auto.low[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n border: 1px solid #fca5a5;\n color: #991b1b;\n}\n\n.tag-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n\n\n.analytics-filters[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n}\n\n.filters-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header[_ngcontent-%COMP%]:hover {\n background: var(--test-bg);\n}\n\n.filters-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.filter-summary[_ngcontent-%COMP%] {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group[_ngcontent-%COMP%] 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.filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\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);\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 border-color: var(--test-primary);\n color: white;\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn[_ngcontent-%COMP%] i.fa-check[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.filter-hint[_ngcontent-%COMP%] {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters[_ngcontent-%COMP%] {\n max-height: 120px;\n overflow-y: auto;\n}\n\n\n\n.analytics-kpis[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\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: #eff6ff;\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-icon.info[_ngcontent-%COMP%] {\n background: #f0f9ff;\n color: #0ea5e9;\n}\n\n.kpi-icon.warning[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.kpi-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: #f1f5f9;\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n\n\n.analytics-table-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.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.clickable-row[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed[_ngcontent-%COMP%] { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-passed[_ngcontent-%COMP%] { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-failed[_ngcontent-%COMP%] { background: #fef2f2; color: var(--test-error); }\n.status-chip.status-error[_ngcontent-%COMP%] { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-running[_ngcontent-%COMP%] { background: #eff6ff; color: var(--test-primary); }\n.status-chip.status-pending[_ngcontent-%COMP%] { background: #f5f3ff; color: #8b5cf6; }\n.status-chip.status-cancelled[_ngcontent-%COMP%] { background: #f1f5f9; color: var(--test-disabled); }\n.status-chip.status-missing[_ngcontent-%COMP%] { background: #f1f5f9; color: var(--test-text-muted); }\n.status-chip.status-timeout[_ngcontent-%COMP%] { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-skipped[_ngcontent-%COMP%] { background: #f1f5f9; color: var(--test-disabled); }\n\n.pass-rate-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar[_ngcontent-%COMP%] {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium[_ngcontent-%COMP%] { background: var(--test-warning); }\n.pass-rate-bar.low[_ngcontent-%COMP%] { background: var(--test-error); }\n\n\n\n.analytics-subnav[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\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.subnav-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.subnav-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.matrix-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.matrix-run-count[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n\n\n.matrix-filter-input[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n background: #f8fafc;\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] i.fa-search[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]::placeholder {\n color: #94a3b8;\n}\n\n.clear-filter-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: #94a3b8;\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn[_ngcontent-%COMP%]:hover {\n background: #e2e8f0;\n color: #64748b;\n}\n\n\n\n.matrix-scroll-container[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix[_ngcontent-%COMP%] {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n display: table-header-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] {\n display: table-row-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: rgba(59, 130, 246, 0.05);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n border-top: 1px solid rgba(59, 130, 246, 0.3);\n border-bottom: 1px solid rgba(59, 130, 246, 0.3);\n}\n\n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.row-selected[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n display: table-footer-group;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid #475569 !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: #64748b;\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; \n\n top: 0;\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .seq-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .seq-header[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-header[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%] {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n\n\n.test-matrix[_ngcontent-%COMP%] .spacer-header[_ngcontent-%COMP%], \n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix[_ngcontent-%COMP%] .spacer-cell[_ngcontent-%COMP%] {\n background: var(--test-surface);\n}\n\n.test-matrix[_ngcontent-%COMP%] .run-header[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-header-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.run-pass-rate.medium[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.run-pass-rate.low[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny[_ngcontent-%COMP%] {\n font-size: 9px;\n padding: 2px 6px;\n background: #eff6ff;\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.run-tags-header[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix[_ngcontent-%COMP%] .test-name-cell[_ngcontent-%COMP%] {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name[_ngcontent-%COMP%] {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell[_ngcontent-%COMP%] {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.result-cell.clickable[_ngcontent-%COMP%]:hover {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n z-index: 5;\n}\n\n.result-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.result-cell.cell-passed[_ngcontent-%COMP%], \n.result-cell.cell-failed[_ngcontent-%COMP%], \n.result-cell.cell-error[_ngcontent-%COMP%], \n.result-cell.cell-timeout[_ngcontent-%COMP%], \n.result-cell.cell-running[_ngcontent-%COMP%], \n.result-cell.cell-pending[_ngcontent-%COMP%] {\n background: #ffffff;\n color: var(--test-text);\n}\n\n\n\n.result-cell.cell-skipped[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none[_ngcontent-%COMP%] {\n background: #f8fafc;\n color: var(--test-text-muted);\n}\n\n.cell-score[_ngcontent-%COMP%] {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n\n\n.cell-eval-stack[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval[_ngcontent-%COMP%] {\n min-width: 120px;\n width: auto;\n}\n\n\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: #f3e8ff;\n color: #7c3aed;\n}\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: #fef3c7;\n color: #d97706;\n font-size: 10px;\n}\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-auto.high[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-auto.medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-auto.low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-none-indicator[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.chart-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.chart-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.chart-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-passed[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-failed[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-error[_ngcontent-%COMP%] {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.chart-legend[_ngcontent-%COMP%] .legend-item.chart-skipped[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: var(--test-disabled);\n}\n\n.chart-container[_ngcontent-%COMP%] {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: linear-gradient(135deg, #fafbff 0%, #f8fafc 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart[_ngcontent-%COMP%] {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart[_ngcontent-%COMP%] svg[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .node[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n.d3-chart[_ngcontent-%COMP%] .node-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%] {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart[_ngcontent-%COMP%] .link[_ngcontent-%COMP%]:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip[_ngcontent-%COMP%] {\n position: absolute;\n padding: 10px 14px;\n background: rgba(30, 41, 59, 0.95);\n color: white;\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n max-width: 250px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-title[_ngcontent-%COMP%] {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart[_ngcontent-%COMP%] .tooltip-value[_ngcontent-%COMP%] {\n opacity: 0.8;\n}\n\n.chart-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n\n\n.compare-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-selection[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list[_ngcontent-%COMP%] {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-selector-item.selected[_ngcontent-%COMP%] {\n border-color: var(--test-primary);\n background: #eff6ff;\n}\n\n.run-selector-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview[_ngcontent-%COMP%] {\n padding: 12px;\n background: #f8fafc;\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn[_ngcontent-%COMP%] {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n\n.preview-details[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n\n\n.compare-results[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.compare-summary[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.compare-summary-card[_ngcontent-%COMP%] .summary-value.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.compare-summary-card.improved[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-success); }\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] { color: var(--test-error); }\n\n\n\n.compare-table-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.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.compare-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.improved[_ngcontent-%COMP%] {\n background: rgba(16, 185, 129, 0.05);\n}\n\n.compare-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr.regressed[_ngcontent-%COMP%] {\n background: rgba(239, 68, 68, 0.05);\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive[_ngcontent-%COMP%] { color: var(--test-success); }\n.negative[_ngcontent-%COMP%] { color: var(--test-error); }\n.muted[_ngcontent-%COMP%] { color: var(--test-text-muted); }\n\n.change-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved[_ngcontent-%COMP%] {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.change-indicator.regressed[_ngcontent-%COMP%] {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.change-indicator.unchanged[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: var(--test-text-muted);\n}\n\n\n\n.compare-empty[_ngcontent-%COMP%] {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-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: 0 auto 20px;\n}\n\n.compare-empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty[_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.compare-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n\n\n.empty-state.small[_ngcontent-%COMP%] {\n padding: 32px 16px;\n}\n\n.empty-state.small[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .compare-selection[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs[_ngcontent-%COMP%] {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .filter-btn[_ngcontent-%COMP%] {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .kpi-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .kpi-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper[_ngcontent-%COMP%], \n .compare-table-wrapper[_ngcontent-%COMP%] {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list[_ngcontent-%COMP%] {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .analytics-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .analytics-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .compare-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n\n\n\n.cell-human[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-human.no-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-human.has-feedback[_ngcontent-%COMP%] .rating-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 11px;\n}\n\n\n\n.cell-human.rating-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-human.rating-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-human.rating-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-human.rating-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.cell-auto[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-auto.no-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n}\n\n.cell-auto.has-score[_ngcontent-%COMP%] .score-value[_ngcontent-%COMP%] {\n font-weight: 700;\n font-size: 10px;\n}\n\n\n\n.cell-auto.score-low[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-auto.score-medium[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-auto.score-good[_ngcontent-%COMP%] {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-auto.score-excellent[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n\n\n.cell-status[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed[_ngcontent-%COMP%] {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.cell-status.status-failed[_ngcontent-%COMP%] {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-status.status-error[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-timeout[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-skipped[_ngcontent-%COMP%], \n.cell-status.status-pending[_ngcontent-%COMP%] {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #2563eb;\n}\n\n\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: #94a3b8;\n}\n\n.result-cell.cell-not-run[_ngcontent-%COMP%] .cell-eval-stack[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: #94a3b8;\n font-size: 11px;\n}\n\n\n\n\n\n.test-matrix[_ngcontent-%COMP%] tfoot[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row[_ngcontent-%COMP%] {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-label[_ngcontent-%COMP%] {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row[_ngcontent-%COMP%] .totals-cell[_ngcontent-%COMP%] {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n}\n\n.totals-stack[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status[_ngcontent-%COMP%], \n.totals-human[_ngcontent-%COMP%], \n.totals-auto[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status[_ngcontent-%COMP%] {\n background: #e0f2fe;\n color: #0369a1;\n}\n\n.totals-status[_ngcontent-%COMP%] .pass-count[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] {\n background: #fef3c7;\n color: #92400e;\n}\n\n.totals-human[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-human[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: #1e40af;\n}\n\n.totals-auto[_ngcontent-%COMP%] .avg-label[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.totals-auto[_ngcontent-%COMP%] .count-label[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.8;\n}"], changeDetection: 0 }); }
|
|
3450
3471
|
};
|
|
3451
3472
|
TestSuiteFormComponentExtended = __decorate([
|
|
3452
3473
|
RegisterClass(BaseFormComponent, 'MJ: Test Suites')
|
|
@@ -3454,15 +3475,15 @@ TestSuiteFormComponentExtended = __decorate([
|
|
|
3454
3475
|
export { TestSuiteFormComponentExtended };
|
|
3455
3476
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestSuiteFormComponentExtended, [{
|
|
3456
3477
|
type: Component,
|
|
3457
|
-
args: [{ selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\" kendoDialogContainer>\n <!-- Header Section -->\n <div class=\"suite-header\">\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>{{ record.Name }}</h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n <span class=\"test-count\" *ngIf=\"testsLoaded\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\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)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button kendoButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n <div class=\"suite-description\" *ngIf=\"record.Description\">\n <p>{{ record.Description }}</p>\n </div>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n <span class=\"tab-badge\" *ngIf=\"testsLoaded\">{{ suiteTests.length }}</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> Runs\n <span class=\"tab-badge\" *ngIf=\"runsLoaded\">{{ suiteRuns.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> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\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 <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Suite 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\">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\">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 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>\n </div>\n\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>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\">Default timeout for tests in this suite</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tests Tab -->\n <div class=\"tests-tab\" *ngIf=\"activeTab === 'tests'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingTests\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3,4,5]\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tests List -->\n <div class=\"tests-list\" *ngIf=\"!loadingTests && suiteTests.length > 0\">\n <div class=\"test-item\" *ngFor=\"let test of suiteTests\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n <span *ngIf=\"test.Status\"><i class=\"fas fa-info-circle\"></i> {{ test.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=\"testsLoaded && !loadingTests && suiteTests.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <h4>No Tests in Suite</h4>\n <p>Add tests to this suite to start running them together.</p>\n </div>\n </div>\n\n <!-- 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]\">\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 && suiteRuns.length > 0\">\n <div class=\"run-item\" *ngFor=\"let run of suiteRuns\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></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.TotalTests\">\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n <span class=\"eval-metric status\" *ngIf=\"evalPreferences.showExecution\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n <!-- Human score (placeholder - need avg from suite run) -->\n <span class=\"eval-metric human\" *ngIf=\"evalPreferences.showHuman\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n <!-- Auto score (pass rate as proxy) -->\n <span class=\"eval-metric auto\" *ngIf=\"evalPreferences.showAuto && run.TotalTests\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n </div>\n <!-- Tags display -->\n <div class=\"run-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-chip\" *ngFor=\"let tag of getRunTags(run)\">{{ tag }}</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"runsLoaded && !loadingRuns && suiteRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Suite Runs Yet</h4>\n <p>Run this suite to see execution history and results here.</p>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n </div>\n\n <!-- Analytics Tab -->\n <div class=\"analytics-tab\" *ngIf=\"activeTab === 'analytics'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingAnalytics\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n\n <ng-container *ngIf=\"!loadingAnalytics && analyticsLoaded\">\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n\n <!-- Collapsible Filters (shared by both views) -->\n <div class=\"analytics-filters\" [class.collapsed]=\"filtersCollapsed\">\n <div class=\"filters-header\" (click)=\"toggleFilters()\">\n <span class=\"filters-title\">\n <i class=\"fas fa-filter\"></i>\n Filters\n <span class=\"filter-summary\" *ngIf=\"filtersCollapsed\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n <span *ngIf=\"selectedTags.length > 0\"> \u00B7 {{ selectedTags.length }} tags</span>\n </span>\n </span>\n <i class=\"fas\" [ngClass]=\"filtersCollapsed ? 'fa-chevron-down' : 'fa-chevron-up'\"></i>\n </div>\n <div class=\"filters-content\" *ngIf=\"!filtersCollapsed\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n <div class=\"filter-group\" *ngIf=\"uniqueTags.length > 0\">\n <label>Filter by Tag <span class=\"filter-hint\" *ngIf=\"selectedTags.length > 0\">({{ selectedTags.length }} selected)</span></label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n <button class=\"filter-btn tag-btn\"\n *ngFor=\"let tag of uniqueTags\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n <i class=\"fas fa-check\" *ngIf=\"isTagSelected(tag)\"></i>\n {{ tag }}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Summary View -->\n <ng-container *ngIf=\"analyticsView === 'summary'\">\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></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\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let dp of getFilteredAnalyticsData()\" (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n <span class=\"tag-chip-table\" *ngFor=\"let tag of dp.tags.slice(0, 2)\">{{ tag }}</span>\n <span class=\"tag-more\" *ngIf=\"dp.tags.length > 2\">+{{ dp.tags.length - 2 }}</span>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n <div class=\"empty-state small\" *ngIf=\"getFilteredAnalyticsData().length === 0\">\n <p>No runs match the current filters.</p>\n </div>\n </div>\n </ng-container>\n\n <!-- Matrix View -->\n <ng-container *ngIf=\"analyticsView === 'matrix'\">\n <!-- Loading Matrix -->\n <div class=\"loading-state\" *ngIf=\"loadingMatrix\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n\n <!-- Matrix Content -->\n <div class=\"matrix-section\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length > 0\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n <button class=\"clear-filter-btn\" *ngIf=\"matrixTestFilter\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button kendoButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"run-header\" *ngFor=\"let run of matrixData\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n <div class=\"run-tags-header\" *ngIf=\"run.tags.length > 0\">\n <span class=\"tag-chip-header\" *ngFor=\"let tag of run.tags.slice(0, 2)\">{{ tag }}</span>\n <span class=\"tag-more-header\" *ngIf=\"run.tags.length > 2\">+{{ run.tags.length - 2 }}</span>\n </div>\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let test of getUniqueTestsFromMatrix()\"\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n <td class=\"result-cell\"\n *ngFor=\"let run of matrixData\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n <ng-container *ngIf=\"getTestResultForRun(run.runId, test.testId) as result\">\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n <span class=\"cell-status\" *ngIf=\"evalPreferences.showExecution\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n <span class=\"cell-human no-feedback\" *ngIf=\"evalPreferences.showHuman && !result.humanRating\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n <span class=\"cell-human has-feedback\" *ngIf=\"evalPreferences.showHuman && result.humanRating\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n <!-- Auto score - colored by percentage -->\n <span class=\"cell-auto has-score\" *ngIf=\"evalPreferences.showAuto && result.score != null\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n <span class=\"cell-auto no-score\" *ngIf=\"evalPreferences.showAuto && result.score == null\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n </div>\n </ng-container>\n <span class=\"cell-not-run-indicator\" *ngIf=\"!getTestResultForRun(run.runId, test.testId)\">\n <i class=\"fas fa-minus\"></i>\n </span>\n </td>\n <td class=\"spacer-cell\"></td>\n </tr>\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n <td class=\"result-cell totals-cell\" *ngFor=\"let run of matrixData\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n <span class=\"totals-status\" *ngIf=\"evalPreferences.showExecution\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n <!-- Human totals -->\n <span class=\"totals-human\" *ngIf=\"evalPreferences.showHuman\">\n <span class=\"avg-label\" *ngIf=\"getRunHumanAvg(run) != null\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n <!-- Auto totals -->\n <span class=\"totals-auto\" *ngIf=\"evalPreferences.showAuto\">\n <span class=\"avg-label\" *ngIf=\"getRunAutoAvg(run) != null\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n </div>\n </td>\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n\n <!-- Empty Matrix State -->\n <div class=\"empty-state\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-th\"></i>\n </div>\n <h4>No Matrix Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n </ng-container>\n\n <!-- Chart View -->\n <ng-container *ngIf=\"analyticsView === 'chart'\">\n <!-- Loading Chart -->\n <div class=\"loading-state\" *ngIf=\"loadingMatrix\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n\n <!-- Chart Content -->\n <div class=\"chart-section\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length > 0\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n\n <!-- Empty Chart State -->\n <div class=\"empty-state\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-project-diagram\"></i>\n </div>\n <h4>No Chart Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n </ng-container>\n </ng-container>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"!loadingAnalytics && analyticsLoaded && analyticsData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No Analytics Data</h4>\n <p>Run this suite to start collecting analytics data.</p>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n </div>\n\n <!-- Compare Tab -->\n <div class=\"compare-tab\" *ngIf=\"activeTab === 'compare'\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n <div class=\"run-selector-list\" *ngIf=\"!loadingRuns && suiteRuns.length > 0\">\n <div class=\"run-selector-item\"\n *ngFor=\"let run of suiteRuns\"\n [class.selected]=\"compareRunA?.ID === run.ID\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n <div class=\"selector-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of getRunTags(run).slice(0, 2)\">{{ tag }}</span>\n </div>\n </div>\n </div>\n <div class=\"selected-run-preview\" *ngIf=\"compareRunA\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n </div>\n\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n <div class=\"run-selector-list\" *ngIf=\"!loadingRuns && suiteRuns.length > 0\">\n <div class=\"run-selector-item\"\n *ngFor=\"let run of suiteRuns\"\n [class.selected]=\"compareRunB?.ID === run.ID\"\n [class.disabled]=\"compareRunA?.ID === run.ID\"\n (click)=\"compareRunA?.ID !== run.ID && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n <div class=\"selector-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of getRunTags(run).slice(0, 2)\">{{ tag }}</span>\n </div>\n </div>\n </div>\n <div class=\"selected-run-preview\" *ngIf=\"compareRunB\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Comparison Results -->\n <div class=\"compare-results\" *ngIf=\"compareRunA && compareRunB && !loadingCompare\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of compareResults\" [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n <span class=\"status-chip\" *ngIf=\"result.runA\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n <span class=\"status-chip status-missing\" *ngIf=\"!result.runA\">N/A</span>\n </td>\n <td>\n <span class=\"status-chip\" *ngIf=\"result.runB\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n <span class=\"status-chip status-missing\" *ngIf=\"!result.runB\">N/A</span>\n </td>\n <td>\n <span *ngIf=\"result.scoreDiff != null\" [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n <span *ngIf=\"result.scoreDiff == null\" class=\"muted\">-</span>\n </td>\n <td>\n <span *ngIf=\"result.durationDiff != null\" [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n <span *ngIf=\"result.durationDiff == null\" class=\"muted\">-</span>\n </td>\n <td>\n <span class=\"change-indicator improved\" *ngIf=\"result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed'\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n <span class=\"change-indicator regressed\" *ngIf=\"result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n <span class=\"change-indicator unchanged\" *ngIf=\"!result.statusChanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Loading State for Compare -->\n <div class=\"loading-state\" *ngIf=\"loadingCompare\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n\n <!-- Empty State -->\n <div class=\"compare-empty\" *ngIf=\"!compareRunA || !compareRunB\">\n <div class=\"compare-empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Select Two Runs to Compare</h4>\n <p>Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.</p>\n </div>\n\n <!-- No Runs State -->\n <div class=\"empty-state\" *ngIf=\"runsLoaded && suiteRuns.length < 2\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Not Enough Runs to Compare</h4>\n <p>You need at least 2 suite runs to use the comparison feature.</p>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\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 Suite</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 Suite Form - World-Class UX\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-success: #10b981;\n --test-error: #ef4444;\n --test-warning: #f59e0b;\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);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-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, sans-serif;\n}\n\n/* Header */\n.suite-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.suite-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.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-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 word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\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}\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 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-count {\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.suite-description {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\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 scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\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-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}\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}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n 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, .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.info-section h3, .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.info-section h3 i, .config-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 font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\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}\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-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\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-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\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-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-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.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-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.test-item:hover, .run-item:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\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.test-icon {\n background: linear-gradient(135deg, var(--test-primary) 0%, #1d4ed8 100%);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Empty States */\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/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--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 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 color: var(--test-text-secondary);\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-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border: 1px solid #bfdbfe;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: #1d4ed8;\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: #f1f5f9;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: #64748b;\n}\n\n.tag-more {\n font-size: 10px;\n color: #94a3b8;\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-metric.status.status-completed {\n background: #dcfce7;\n color: #166534;\n}\n\n.eval-metric.status.status-failed {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.eval-metric.status.status-running {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.eval-metric.status.status-pending {\n background: #fef3c7;\n color: #92400e;\n}\n\n.eval-metric.human {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #f59e0b;\n color: #92400e;\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: #d97706;\n}\n\n.eval-metric.auto {\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n}\n\n.eval-metric.auto.high {\n background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);\n border: 1px solid #86efac;\n color: #166534;\n}\n\n.eval-metric.auto.medium {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #fcd34d;\n color: #92400e;\n}\n\n.eval-metric.auto.low {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n border: 1px solid #fca5a5;\n color: #991b1b;\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n.analytics-filters {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed {\n margin-bottom: 12px;\n}\n\n.filters-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header:hover {\n background: var(--test-bg);\n}\n\n.filters-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title i {\n color: var(--test-primary);\n}\n\n.filter-summary {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header > i {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group 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.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\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);\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 border-color: var(--test-primary);\n color: white;\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\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: #eff6ff;\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: #f0f9ff;\n color: #0ea5e9;\n}\n\n.kpi-icon.warning {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: #f1f5f9;\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-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.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-passed { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-failed { background: #fef2f2; color: var(--test-error); }\n.status-chip.status-error { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-running { background: #eff6ff; color: var(--test-primary); }\n.status-chip.status-pending { background: #f5f3ff; color: #8b5cf6; }\n.status-chip.status-cancelled { background: #f1f5f9; color: var(--test-disabled); }\n.status-chip.status-missing { background: #f1f5f9; color: var(--test-text-muted); }\n.status-chip.status-timeout { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-skipped { background: #f1f5f9; color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\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.subnav-tab:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: #f8fafc;\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: #94a3b8;\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: #94a3b8;\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: #e2e8f0;\n color: #64748b;\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: rgba(59, 130, 246, 0.05);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid rgba(59, 130, 246, 0.3);\n border-bottom: 1px solid rgba(59, 130, 246, 0.3);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid #475569 !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: #64748b;\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: #f1f5f9;\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: #f1f5f9;\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: #eff6ff;\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: #ffffff;\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: #f8fafc;\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-status.status-failed {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-status.status-error {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-status.status-skipped {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-status.status-pending {\n background: #f3e8ff;\n color: #7c3aed;\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: #fef3c7;\n color: #d97706;\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-auto.high {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-auto.medium {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-auto.low {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-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.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: #f1f5f9;\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: linear-gradient(135deg, #fafbff 0%, #f8fafc 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: rgba(30, 41, 59, 0.95);\n color: white;\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: #eff6ff;\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: #f8fafc;\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-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.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: rgba(16, 185, 129, 0.05);\n}\n\n.compare-table tbody tr.regressed {\n background: rgba(239, 68, 68, 0.05);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: #f1f5f9;\n color: var(--test-text-muted);\n}\n\n/* Compare Empty State */\n.compare-empty {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-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: 0 auto 20px;\n}\n\n.compare-empty-icon i {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.compare-empty p {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n/* Small empty state variant */\n.empty-state.small {\n padding: 32px 16px;\n}\n\n.empty-state.small p {\n margin: 0;\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-human.rating-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-human.rating-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-human.rating-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-auto.score-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-auto.score-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-auto.score-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.cell-status.status-failed {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-status.status-error {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-timeout {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running {\n background: #dbeafe;\n color: #2563eb;\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: #94a3b8;\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: #94a3b8;\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: #e0f2fe;\n color: #0369a1;\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: #fef3c7;\n color: #92400e;\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: #dbeafe;\n color: #1e40af;\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n"] }]
|
|
3458
|
-
}], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i3.TestingDialogService }, { type: i3.EvaluationPreferencesService }, { type: i0.ViewContainerRef }], { chartContainer: [{
|
|
3478
|
+
args: [{ selector: 'mj-test-suite-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-form\" kendoDialogContainer>\n <!-- Header Section -->\n <div class=\"suite-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-layer-group\"></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=\"suite-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-layer-group\"></i>\n </div>\n <div class=\"suite-info\">\n <h1>{{ record.Name }}</h1>\n <div class=\"suite-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"record.Status === 'Active' ? 'fa-circle-check' : 'fa-circle-pause'\"></i>\n {{ record.Status }}\n </span>\n <span class=\"test-count\" *ngIf=\"testsLoaded\">\n <i class=\"fas fa-flask\"></i>\n {{ suiteTests.length }} tests\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)=\"exportToExcel()\" title=\"Export to CSV\">\n <i class=\"fas fa-file-excel\"></i> Export\n </button>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite\n </button>\n <button kendoButton (click)=\"refresh()\" [disabled]=\"isRefreshing\">\n <i class=\"fas\" [ngClass]=\"isRefreshing ? 'fa-sync fa-spin' : 'fa-sync'\"></i>\n {{ isRefreshing ? 'Refreshing...' : 'Refresh' }}\n </button>\n </div>\n </div>\n <div class=\"suite-description\" *ngIf=\"record.Description\">\n <p>{{ record.Description }}</p>\n </div>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\"\n [class.active]=\"activeTab === 'overview'\"\n (click)=\"changeTab('overview')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'overview'\">\n <i class=\"fas fa-th-large\"></i> Overview\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'tests'\"\n (click)=\"changeTab('tests')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'tests'\">\n <i class=\"fas fa-flask\"></i> Tests\n <span class=\"tab-badge\" *ngIf=\"testsLoaded\">{{ suiteTests.length }}</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> Runs\n <span class=\"tab-badge\" *ngIf=\"runsLoaded\">{{ suiteRuns.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> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'compare'\"\n (click)=\"changeTab('compare')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'compare'\">\n <i class=\"fas fa-balance-scale\"></i> Compare\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 <div class=\"info-section\">\n <h3><i class=\"fas fa-info-circle\"></i> Suite 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\">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\">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 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>\n </div>\n\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>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\">Default timeout for tests in this suite</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tests Tab -->\n <div class=\"tests-tab\" *ngIf=\"activeTab === 'tests'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingTests\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3,4,5]\">\n <div class=\"skeleton-sequence\"></div>\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Tests List -->\n <div class=\"tests-list\" *ngIf=\"!loadingTests && suiteTests.length > 0\">\n <div class=\"test-item\" *ngFor=\"let test of suiteTests\" (click)=\"openTest(test.TestID)\">\n <div class=\"test-sequence\">{{ test.Sequence }}</div>\n <div class=\"test-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"test-content\">\n <div class=\"test-name\">{{ test.Test }}</div>\n <div class=\"test-status\">\n <span *ngIf=\"test.Status\"><i class=\"fas fa-info-circle\"></i> {{ test.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=\"testsLoaded && !loadingTests && suiteTests.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <h4>No Tests in Suite</h4>\n <p>Add tests to this suite to start running them together.</p>\n </div>\n </div>\n\n <!-- 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]\">\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 && suiteRuns.length > 0\">\n <div class=\"run-item\" *ngFor=\"let run of suiteRuns\" (click)=\"openSuiteRun(run.ID)\">\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\"\n [class.fa-check]=\"run.Status === 'Completed'\"\n [class.fa-times]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></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.TotalTests\">\n <i class=\"fas fa-check-circle\"></i> {{ run.PassedTests }}/{{ run.TotalTests }}\n ({{ getPassRate(run).toFixed(0) }}%)\n </span>\n </div>\n <!-- Evaluation metrics row -->\n <div class=\"run-eval-metrics\">\n <!-- Status badge -->\n <span class=\"eval-metric status\" *ngIf=\"evalPreferences.showExecution\" [class]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-circle-check]=\"run.Status === 'Completed'\"\n [class.fa-circle-xmark]=\"run.Status === 'Failed'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-ban]=\"run.Status === 'Cancelled'\"></i>\n </span>\n <!-- Human score (placeholder - need avg from suite run) -->\n <span class=\"eval-metric human\" *ngIf=\"evalPreferences.showHuman\" title=\"Human evaluation\">\n <i class=\"fas fa-user\"></i>\n <span class=\"eval-pending\"><i class=\"fas fa-clock\"></i></span>\n </span>\n <!-- Auto score (pass rate as proxy) -->\n <span class=\"eval-metric auto\" *ngIf=\"evalPreferences.showAuto && run.TotalTests\"\n [class.high]=\"getPassRate(run) >= 80\"\n [class.medium]=\"getPassRate(run) >= 50 && getPassRate(run) < 80\"\n [class.low]=\"getPassRate(run) < 50\"\n title=\"Auto score (pass rate)\">\n <i class=\"fas fa-robot\"></i>\n <span>{{ getPassRate(run).toFixed(0) }}%</span>\n </span>\n </div>\n <!-- Tags display -->\n <div class=\"run-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-chip\" *ngFor=\"let tag of getRunTags(run)\">{{ tag }}</span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right\"></i>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"runsLoaded && !loadingRuns && suiteRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-play-circle\"></i>\n </div>\n <h4>No Suite Runs Yet</h4>\n <p>Run this suite to see execution history and results here.</p>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n </div>\n\n <!-- Analytics Tab -->\n <div class=\"analytics-tab\" *ngIf=\"activeTab === 'analytics'\">\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingAnalytics\">\n <mj-loading text=\"Loading analytics data...\"></mj-loading>\n </div>\n\n <ng-container *ngIf=\"!loadingAnalytics && analyticsLoaded\">\n <!-- View Toggle Sub-nav -->\n <div class=\"analytics-subnav\">\n <div class=\"subnav-tabs\">\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'summary'\"\n (click)=\"setAnalyticsView('summary')\">\n <i class=\"fas fa-chart-bar\"></i>\n <span>Summary</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'matrix'\"\n (click)=\"setAnalyticsView('matrix')\">\n <i class=\"fas fa-th\"></i>\n <span>Matrix</span>\n </button>\n <button class=\"subnav-tab\"\n [class.active]=\"analyticsView === 'chart'\"\n (click)=\"setAnalyticsView('chart')\">\n <i class=\"fas fa-project-diagram\"></i>\n <span>Chart</span>\n </button>\n </div>\n </div>\n\n <!-- Collapsible Filters (shared by both views) -->\n <div class=\"analytics-filters\" [class.collapsed]=\"filtersCollapsed\">\n <div class=\"filters-header\" (click)=\"toggleFilters()\">\n <span class=\"filters-title\">\n <i class=\"fas fa-filter\"></i>\n Filters\n <span class=\"filter-summary\" *ngIf=\"filtersCollapsed\">\n {{ analyticsTimeRange === 'all' ? 'All Time' : analyticsTimeRange }}\n <span *ngIf=\"selectedTags.length > 0\"> \u00B7 {{ selectedTags.length }} tags</span>\n </span>\n </span>\n <i class=\"fas\" [ngClass]=\"filtersCollapsed ? 'fa-chevron-down' : 'fa-chevron-up'\"></i>\n </div>\n <div class=\"filters-content\" *ngIf=\"!filtersCollapsed\">\n <div class=\"filter-group\">\n <label>Time Range</label>\n <div class=\"filter-buttons\">\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '7d'\" (click)=\"setTimeRange('7d')\">7 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '30d'\" (click)=\"setTimeRange('30d')\">30 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === '90d'\" (click)=\"setTimeRange('90d')\">90 Days</button>\n <button class=\"filter-btn\" [class.active]=\"analyticsTimeRange === 'all'\" (click)=\"setTimeRange('all')\">All Time</button>\n </div>\n </div>\n <div class=\"filter-group\" *ngIf=\"uniqueTags.length > 0\">\n <label>Filter by Tag <span class=\"filter-hint\" *ngIf=\"selectedTags.length > 0\">({{ selectedTags.length }} selected)</span></label>\n <div class=\"filter-buttons tag-filters\">\n <button class=\"filter-btn tag-btn all-tags-btn\"\n [class.active]=\"selectedTags.length === 0\"\n (click)=\"toggleTagFilter(null)\">\n <i class=\"fas fa-layer-group\"></i> All Tags\n </button>\n <button class=\"filter-btn tag-btn\"\n *ngFor=\"let tag of uniqueTags\"\n [class.active]=\"isTagSelected(tag)\"\n (click)=\"toggleTagFilter(tag)\">\n <i class=\"fas fa-check\" *ngIf=\"isTagSelected(tag)\"></i>\n {{ tag }}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Summary View -->\n <ng-container *ngIf=\"analyticsView === 'summary'\">\n <!-- KPI Cards -->\n <div class=\"analytics-kpis\">\n <div class=\"kpi-card\">\n <div class=\"kpi-icon\"><i class=\"fas fa-play-circle\"></i></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\">\n <div class=\"kpi-icon success\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ getAveragePassRate().toFixed(1) }}%</div>\n <div class=\"kpi-label\">Avg Pass Rate</div>\n <div class=\"kpi-trend\" [ngClass]=\"{'trend-up': getPassRateTrend().direction === 'up', 'trend-down': getPassRateTrend().direction === 'down'}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getPassRateTrend().direction === 'up', 'fa-arrow-down': getPassRateTrend().direction === 'down', 'fa-minus': getPassRateTrend().direction === 'stable'}\"></i>\n {{ getPassRateTrend().value.toFixed(1) }}%\n </div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon info\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatDuration(getAverageDuration()) }}</div>\n <div class=\"kpi-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"kpi-card\">\n <div class=\"kpi-icon warning\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"kpi-content\">\n <div class=\"kpi-value\">{{ formatCost(getTotalCost()) }}</div>\n <div class=\"kpi-label\">Total Cost</div>\n </div>\n </div>\n </div>\n\n <!-- Runs Table -->\n <div class=\"analytics-table-section\">\n <h3><i class=\"fas fa-table\"></i> Run History</h3>\n <div class=\"analytics-table-wrapper\">\n <table class=\"analytics-table\">\n <thead>\n <tr>\n <th>Date</th>\n <th>Status</th>\n <th>Pass Rate</th>\n <th>Tests</th>\n <th>Duration</th>\n <th>Cost</th>\n <th>Tags</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let dp of getFilteredAnalyticsData()\" (click)=\"openSuiteRun(dp.runId)\" class=\"clickable-row\">\n <td>{{ dp.date | date:'short' }}</td>\n <td>\n <span class=\"status-chip\" [ngClass]=\"'status-' + dp.status.toLowerCase()\">{{ dp.status }}</span>\n </td>\n <td>\n <div class=\"pass-rate-cell\">\n <div class=\"pass-rate-bar\" [style.width.%]=\"dp.passRate\" [ngClass]=\"{'high': dp.passRate >= 80, 'medium': dp.passRate >= 50 && dp.passRate < 80, 'low': dp.passRate < 50}\"></div>\n <span>{{ dp.passRate.toFixed(0) }}%</span>\n </div>\n </td>\n <td>{{ dp.passedTests }}/{{ dp.totalTests }}</td>\n <td>{{ formatDuration(dp.duration) }}</td>\n <td>{{ formatCost(dp.cost) }}</td>\n <td>\n <div class=\"tag-cell\">\n <span class=\"tag-chip-table\" *ngFor=\"let tag of dp.tags.slice(0, 2)\">{{ tag }}</span>\n <span class=\"tag-more\" *ngIf=\"dp.tags.length > 2\">+{{ dp.tags.length - 2 }}</span>\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n <div class=\"empty-state small\" *ngIf=\"getFilteredAnalyticsData().length === 0\">\n <p>No runs match the current filters.</p>\n </div>\n </div>\n </ng-container>\n\n <!-- Matrix View -->\n <ng-container *ngIf=\"analyticsView === 'matrix'\">\n <!-- Loading Matrix -->\n <div class=\"loading-state\" *ngIf=\"loadingMatrix\">\n <mj-loading text=\"Loading test matrix...\"></mj-loading>\n </div>\n\n <!-- Matrix Content -->\n <div class=\"matrix-section\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length > 0\">\n <div class=\"matrix-header\">\n <h3><i class=\"fas fa-th\"></i> Test Results Matrix</h3>\n <div class=\"matrix-header-right\">\n <div class=\"matrix-filter-input\">\n <i class=\"fas fa-search\"></i>\n <input type=\"text\"\n placeholder=\"Filter tests...\"\n [value]=\"matrixTestFilter\"\n (input)=\"onMatrixFilterInput($event)\"\n class=\"filter-input\">\n <button class=\"clear-filter-btn\" *ngIf=\"matrixTestFilter\" (click)=\"clearMatrixFilter()\" title=\"Clear filter\">\n <i class=\"fas fa-times\"></i>\n </button>\n </div>\n <span class=\"matrix-run-count\">{{ matrixData.length }} runs \u00B7 {{ getUniqueTestsFromMatrix().length }} tests</span>\n <button kendoButton (click)=\"exportMatrixToCSV()\" [disabled]=\"matrixData.length === 0\" title=\"Export matrix to CSV\">\n <i class=\"fas fa-download\"></i> Export\n </button>\n </div>\n </div>\n\n <div class=\"matrix-scroll-container\">\n <table class=\"test-matrix\">\n <thead>\n <tr>\n <th class=\"seq-header\" (click)=\"toggleMatrixSort('sequence')\" title=\"Sort by sequence\">\n #\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'sequence' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"test-name-header\" (click)=\"toggleMatrixSort('name')\" title=\"Sort by name\">\n Test\n <i class=\"fas\" [ngClass]=\"matrixSortBy === 'name' ? (matrixSortAsc ? 'fa-sort-up' : 'fa-sort-down') : 'fa-sort'\"></i>\n </th>\n <th class=\"run-header\" *ngFor=\"let run of matrixData\" (click)=\"openSuiteRun(run.runId)\" [title]=\"'Click to view suite run - ' + (run.date | date:'medium')\">\n <div class=\"run-header-content\">\n <div class=\"run-tags-header\" *ngIf=\"run.tags.length > 0\">\n <span class=\"tag-chip-header\" *ngFor=\"let tag of run.tags.slice(0, 2)\">{{ tag }}</span>\n <span class=\"tag-more-header\" *ngIf=\"run.tags.length > 2\">+{{ run.tags.length - 2 }}</span>\n </div>\n <div class=\"run-date\">{{ getRelativeTime(run.date) }}</div>\n <div class=\"run-pass-rate\" [ngClass]=\"{'high': run.passRate >= 80, 'medium': run.passRate >= 50 && run.passRate < 80, 'low': run.passRate < 50}\">\n {{ run.passRate.toFixed(0) }}%\n </div>\n </div>\n </th>\n <th class=\"spacer-header\"></th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let test of getUniqueTestsFromMatrix()\"\n [class.row-selected]=\"selectedMatrixTestId === test.testId\"\n (click)=\"selectMatrixRow(test.testId)\">\n <td class=\"seq-cell\">{{ test.sequence }}</td>\n <td class=\"test-name-cell\">\n <span class=\"test-name\" [title]=\"test.testName\">{{ test.testName }}</span>\n </td>\n <td class=\"result-cell\"\n *ngFor=\"let run of matrixData\"\n [ngClass]=\"getMatrixCellClass(getTestResultForRun(run.runId, test.testId))\"\n [class.clickable]=\"getTestResultForRun(run.runId, test.testId)\"\n [class.cell-not-run]=\"!getTestResultForRun(run.runId, test.testId)\"\n [title]=\"getTestResultForRun(run.runId, test.testId)?.status + ' - Click to view test run' || 'Not Run'\"\n (click)=\"onMatrixCellClick(getTestResultForRun(run.runId, test.testId), $event)\">\n <ng-container *ngIf=\"getTestResultForRun(run.runId, test.testId) as result\">\n <div class=\"cell-eval-stack\">\n <!-- Status indicator -->\n <span class=\"cell-status\" *ngIf=\"evalPreferences.showExecution\"\n [ngClass]=\"'status-' + result.status.toLowerCase()\"\n [class.cell-skipped-status]=\"result.status === 'Skipped' || result.status === 'Pending'\"\n [title]=\"getStatusTooltip(result.status)\">\n <i class=\"fas\"\n [class.fa-check]=\"result.status === 'Passed'\"\n [class.fa-times]=\"result.status === 'Failed'\"\n [class.fa-exclamation]=\"result.status === 'Error'\"\n [class.fa-hourglass-end]=\"result.status === 'Timeout'\"\n [class.fa-forward]=\"result.status === 'Skipped'\"\n [class.fa-spinner]=\"result.status === 'Running'\"\n [class.fa-clock]=\"result.status === 'Pending'\"></i>\n </span>\n <!-- Human score - slashed icon if no feedback, colored by rating if has feedback -->\n <span class=\"cell-human no-feedback\" *ngIf=\"evalPreferences.showHuman && !result.humanRating\"\n title=\"Human Review: No rating submitted yet\">\n <i class=\"fas fa-user-slash\"></i>\n </span>\n <span class=\"cell-human has-feedback\" *ngIf=\"evalPreferences.showHuman && result.humanRating\"\n [class.rating-low]=\"result.humanRating <= 4\"\n [class.rating-medium]=\"result.humanRating >= 5 && result.humanRating <= 6\"\n [class.rating-good]=\"result.humanRating >= 7 && result.humanRating <= 8\"\n [class.rating-excellent]=\"result.humanRating >= 9\"\n [title]=\"getHumanTooltip(result.humanRating, result.humanComments)\">\n <i class=\"fas fa-user\"></i>\n <span class=\"rating-value\">{{ result.humanRating }}</span>\n </span>\n <!-- Auto score - colored by percentage -->\n <span class=\"cell-auto has-score\" *ngIf=\"evalPreferences.showAuto && result.score != null\"\n [class.score-low]=\"result.score < 0.5\"\n [class.score-medium]=\"result.score >= 0.5 && result.score < 0.7\"\n [class.score-good]=\"result.score >= 0.7 && result.score < 0.85\"\n [class.score-excellent]=\"result.score >= 0.85\"\n [title]=\"'Auto Score: ' + (result.score * 100).toFixed(0) + '% automated evaluation'\">\n <i class=\"fas fa-robot\"></i>\n <span class=\"score-value\">{{ (result.score * 100).toFixed(0) }}</span>\n </span>\n <span class=\"cell-auto no-score\" *ngIf=\"evalPreferences.showAuto && result.score == null\"\n title=\"Auto Score: No automated score available\">\n <i class=\"fas fa-robot\"></i>\n </span>\n </div>\n </ng-container>\n <span class=\"cell-not-run-indicator\" *ngIf=\"!getTestResultForRun(run.runId, test.testId)\">\n <i class=\"fas fa-minus\"></i>\n </span>\n </td>\n <td class=\"spacer-cell\"></td>\n </tr>\n </tbody>\n <!-- Footer row with totals -->\n <tfoot>\n <tr class=\"totals-row\">\n <td class=\"seq-cell totals-label\"></td>\n <td class=\"test-name-cell totals-label\">\n <strong>Totals</strong>\n </td>\n <td class=\"result-cell totals-cell\" *ngFor=\"let run of matrixData\">\n <div class=\"cell-eval-stack totals-stack\">\n <!-- Status totals -->\n <span class=\"totals-status\" *ngIf=\"evalPreferences.showExecution\">\n <span class=\"pass-count\">{{ getRunPassedCount(run) }}/{{ getRunTotalCount(run) }}</span>\n </span>\n <!-- Human totals -->\n <span class=\"totals-human\" *ngIf=\"evalPreferences.showHuman\">\n <span class=\"avg-label\" *ngIf=\"getRunHumanAvg(run) != null\">{{ getRunHumanAvg(run)?.toFixed(1) }}</span>\n <span class=\"count-label\">({{ getRunHumanCount(run) }})</span>\n </span>\n <!-- Auto totals -->\n <span class=\"totals-auto\" *ngIf=\"evalPreferences.showAuto\">\n <span class=\"avg-label\" *ngIf=\"getRunAutoAvg(run) != null\">{{ (getRunAutoAvg(run)! * 100).toFixed(0) }}%</span>\n <span class=\"count-label\">({{ getRunAutoCount(run) }})</span>\n </span>\n </div>\n </td>\n <td class=\"spacer-cell\"></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n\n <!-- Empty Matrix State -->\n <div class=\"empty-state\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-th\"></i>\n </div>\n <h4>No Matrix Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n </ng-container>\n\n <!-- Chart View -->\n <ng-container *ngIf=\"analyticsView === 'chart'\">\n <!-- Loading Chart -->\n <div class=\"loading-state\" *ngIf=\"loadingMatrix\">\n <mj-loading text=\"Loading chart data...\"></mj-loading>\n </div>\n\n <!-- Chart Content -->\n <div class=\"chart-section\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length > 0\">\n <div class=\"chart-header\">\n <h3><i class=\"fas fa-project-diagram\"></i> Test Results Flow</h3>\n <div class=\"chart-legend\">\n <span class=\"legend-item chart-passed\"><i class=\"fas fa-check\"></i> Passed</span>\n <span class=\"legend-item chart-failed\"><i class=\"fas fa-times\"></i> Failed</span>\n <span class=\"legend-item chart-error\"><i class=\"fas fa-exclamation\"></i> Error</span>\n <span class=\"legend-item chart-skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n\n <div class=\"chart-container\">\n <div #chartContainer class=\"d3-chart\"></div>\n </div>\n\n <div class=\"chart-info\">\n <i class=\"fas fa-info-circle\"></i>\n Interactive visualization showing test results across {{ matrixData.length }} runs.\n Hover over elements for details, click nodes to navigate.\n </div>\n </div>\n\n <!-- Empty Chart State -->\n <div class=\"empty-state\" *ngIf=\"!loadingMatrix && matrixLoaded && matrixData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-project-diagram\"></i>\n </div>\n <h4>No Chart Data</h4>\n <p>No suite runs match the current filters.</p>\n </div>\n </ng-container>\n </ng-container>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"!loadingAnalytics && analyticsLoaded && analyticsData.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-line\"></i>\n </div>\n <h4>No Analytics Data</h4>\n <p>Run this suite to start collecting analytics data.</p>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\n </div>\n </div>\n\n <!-- Compare Tab -->\n <div class=\"compare-tab\" *ngIf=\"activeTab === 'compare'\">\n <!-- Run Selection -->\n <div class=\"compare-selection\">\n <div class=\"compare-run-selector\">\n <h4>Run A (Baseline)</h4>\n <div class=\"run-selector-list\" *ngIf=\"!loadingRuns && suiteRuns.length > 0\">\n <div class=\"run-selector-item\"\n *ngFor=\"let run of suiteRuns\"\n [class.selected]=\"compareRunA?.ID === run.ID\"\n (click)=\"selectCompareRunA(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n <div class=\"selector-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of getRunTags(run).slice(0, 2)\">{{ tag }}</span>\n </div>\n </div>\n </div>\n <div class=\"selected-run-preview\" *ngIf=\"compareRunA\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunA = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunA.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunA).toFixed(1) }}%</span>\n </div>\n </div>\n </div>\n\n <div class=\"compare-vs\"><i class=\"fas fa-exchange-alt\"></i></div>\n\n <div class=\"compare-run-selector\">\n <h4>Run B (Compare)</h4>\n <div class=\"run-selector-list\" *ngIf=\"!loadingRuns && suiteRuns.length > 0\">\n <div class=\"run-selector-item\"\n *ngFor=\"let run of suiteRuns\"\n [class.selected]=\"compareRunB?.ID === run.ID\"\n [class.disabled]=\"compareRunA?.ID === run.ID\"\n (click)=\"compareRunA?.ID !== run.ID && selectCompareRunB(run)\">\n <div class=\"selector-status\" [style.background-color]=\"getRunStatusColor(run.Status)\"></div>\n <div class=\"selector-content\">\n <div class=\"selector-date\">{{ run.StartedAt | date:'short' }}</div>\n <div class=\"selector-rate\">{{ getPassRate(run).toFixed(0) }}% pass</div>\n </div>\n <div class=\"selector-tags\" *ngIf=\"getRunTags(run).length > 0\">\n <span class=\"tag-mini\" *ngFor=\"let tag of getRunTags(run).slice(0, 2)\">{{ tag }}</span>\n </div>\n </div>\n </div>\n <div class=\"selected-run-preview\" *ngIf=\"compareRunB\">\n <div class=\"preview-header\">\n <span class=\"preview-label\">Selected:</span>\n <button class=\"clear-btn\" (click)=\"compareRunB = null; compareResults = []\">Clear</button>\n </div>\n <div class=\"preview-details\">\n <span>{{ compareRunB.StartedAt | date:'medium' }}</span>\n <span class=\"preview-rate\">{{ getPassRate(compareRunB).toFixed(1) }}%</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Comparison Results -->\n <div class=\"compare-results\" *ngIf=\"compareRunA && compareRunB && !loadingCompare\">\n <!-- Summary Cards -->\n <div class=\"compare-summary\">\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Pass Rate Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getComparePassRateDiff()! > 0, 'negative': getComparePassRateDiff()! < 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-up': getComparePassRateDiff()! > 0, 'fa-arrow-down': getComparePassRateDiff()! < 0, 'fa-minus': getComparePassRateDiff() === 0}\"></i>\n {{ getComparePassRateDiff()! > 0 ? '+' : '' }}{{ getComparePassRateDiff()?.toFixed(1) }}%\n </div>\n </div>\n <div class=\"compare-summary-card\">\n <div class=\"summary-label\">Duration Change</div>\n <div class=\"summary-value\" [ngClass]=\"{'positive': getCompareDurationDiff()! < 0, 'negative': getCompareDurationDiff()! > 0}\">\n <i class=\"fas\" [ngClass]=\"{'fa-arrow-down': getCompareDurationDiff()! < 0, 'fa-arrow-up': getCompareDurationDiff()! > 0, 'fa-minus': getCompareDurationDiff() === 0}\"></i>\n {{ formatDuration(getAbsCompareDurationDiff()) }}\n </div>\n </div>\n <div class=\"compare-summary-card improved\">\n <div class=\"summary-label\">Improved</div>\n <div class=\"summary-value\">{{ getCompareImprovedCount() }}</div>\n </div>\n <div class=\"compare-summary-card regressed\">\n <div class=\"summary-label\">Regressed</div>\n <div class=\"summary-value\">{{ getCompareRegressedCount() }}</div>\n </div>\n </div>\n\n <!-- Detailed Comparison Table -->\n <div class=\"compare-table-section\">\n <h3><i class=\"fas fa-list\"></i> Test-by-Test Comparison</h3>\n <div class=\"compare-table-wrapper\">\n <table class=\"compare-table\">\n <thead>\n <tr>\n <th>Test</th>\n <th>Run A Status</th>\n <th>Run B Status</th>\n <th>Score Diff</th>\n <th>Duration Diff</th>\n <th>Change</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of compareResults\" [ngClass]=\"{'improved': result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed', 'regressed': result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'}\">\n <td class=\"test-name-cell\">{{ result.testName }}</td>\n <td>\n <span class=\"status-chip\" *ngIf=\"result.runA\" [ngClass]=\"'status-' + result.runA.status.toLowerCase()\">{{ result.runA.status }}</span>\n <span class=\"status-chip status-missing\" *ngIf=\"!result.runA\">N/A</span>\n </td>\n <td>\n <span class=\"status-chip\" *ngIf=\"result.runB\" [ngClass]=\"'status-' + result.runB.status.toLowerCase()\">{{ result.runB.status }}</span>\n <span class=\"status-chip status-missing\" *ngIf=\"!result.runB\">N/A</span>\n </td>\n <td>\n <span *ngIf=\"result.scoreDiff != null\" [ngClass]=\"{'positive': result.scoreDiff > 0, 'negative': result.scoreDiff < 0}\">\n {{ result.scoreDiff > 0 ? '+' : '' }}{{ (result.scoreDiff * 100).toFixed(1) }}%\n </span>\n <span *ngIf=\"result.scoreDiff == null\" class=\"muted\">-</span>\n </td>\n <td>\n <span *ngIf=\"result.durationDiff != null\" [ngClass]=\"{'positive': result.durationDiff < 0, 'negative': result.durationDiff > 0}\">\n {{ result.durationDiff > 0 ? '+' : '' }}{{ result.durationDiff.toFixed(1) }}s\n </span>\n <span *ngIf=\"result.durationDiff == null\" class=\"muted\">-</span>\n </td>\n <td>\n <span class=\"change-indicator improved\" *ngIf=\"result.runA && result.runB && result.runA.status !== 'Passed' && result.runB.status === 'Passed'\">\n <i class=\"fas fa-arrow-up\"></i> Fixed\n </span>\n <span class=\"change-indicator regressed\" *ngIf=\"result.runA && result.runB && result.runA.status === 'Passed' && result.runB.status !== 'Passed'\">\n <i class=\"fas fa-arrow-down\"></i> Broke\n </span>\n <span class=\"change-indicator unchanged\" *ngIf=\"!result.statusChanged\">\n <i class=\"fas fa-minus\"></i>\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <!-- Loading State for Compare -->\n <div class=\"loading-state\" *ngIf=\"loadingCompare\">\n <mj-loading text=\"Loading comparison data...\"></mj-loading>\n </div>\n\n <!-- Empty State -->\n <div class=\"compare-empty\" *ngIf=\"!compareRunA || !compareRunB\">\n <div class=\"compare-empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Select Two Runs to Compare</h4>\n <p>Choose a baseline run (A) and a comparison run (B) from the lists above to see a detailed side-by-side comparison.</p>\n </div>\n\n <!-- No Runs State -->\n <div class=\"empty-state\" *ngIf=\"runsLoaded && suiteRuns.length < 2\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-balance-scale\"></i>\n </div>\n <h4>Not Enough Runs to Compare</h4>\n <p>You need at least 2 suite runs to use the comparison feature.</p>\n <button kendoButton (click)=\"runSuite()\" themeColor=\"primary\">\n <i class=\"fas fa-play\"></i> Run Suite Now\n </button>\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 Suite</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 Suite Form - World-Class UX\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-success: #10b981;\n --test-error: #ef4444;\n --test-warning: #f59e0b;\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);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n.test-suite-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, sans-serif;\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/* Header */\n.suite-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.suite-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.suite-icon:hover { transform: scale(1.05); }\n\n.suite-info { flex: 1; min-width: 0; }\n\n.suite-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 word-wrap: break-word;\n}\n\n.suite-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\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}\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 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-count {\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.suite-description {\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.suite-description p {\n margin: 0;\n color: var(--test-text-secondary);\n line-height: 1.6;\n font-size: 14px;\n}\n\n/* Tabs */\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 scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar { display: none; }\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-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}\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}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n 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, .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.info-section h3, .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.info-section h3 i, .config-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 font-weight: 500;\n}\n\n.config-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 20px;\n}\n\n.config-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\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}\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-hint {\n font-size: 11px;\n color: var(--test-text-muted);\n}\n\n/* Tests Tab */\n.tests-tab, .runs-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.loading-state { padding: 0; }\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-sequence {\n width: 32px;\n height: 32px;\n border-radius: 50%;\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-icon {\n width: 40px;\n height: 40px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-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.tests-list, .runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-item, .run-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.test-item:hover, .run-item:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.test-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text-secondary);\n flex-shrink: 0;\n}\n\n.test-icon, .run-icon {\n width: 40px;\n height: 40px;\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.test-icon {\n background: linear-gradient(135deg, var(--test-primary) 0%, #1d4ed8 100%);\n}\n\n.test-content, .run-content { flex: 1; min-width: 0; }\n\n.test-name, .run-header {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.run-header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.run-id { font-weight: 600; }\n\n.run-status {\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n}\n\n.test-status, .run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: var(--test-text-secondary);\n}\n\n.test-status span, .run-meta span {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n}\n\n.test-item > i, .run-item > i {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.test-item:hover > i, .run-item:hover > i {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* Empty States */\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/* Keyboard Shortcuts */\n/* Keyboard shortcuts toggle button - visible when shortcuts are hidden */\n.shortcuts-toggle {\n position: fixed;\n bottom: 20px;\n right: 20px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n background: var(--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 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 color: var(--test-text-secondary);\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-size: 11px;\n color: var(--test-text);\n}\n\n/* Responsive */\n@media (max-width: 1024px) {\n .keyboard-shortcuts, .shortcuts-toggle { display: none; }\n}\n\n@media (max-width: 768px) {\n .suite-header { padding: 16px; }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button { flex: 1; }\n\n .tab-shortcut { display: none; }\n\n .info-grid { grid-template-columns: 1fr; }\n\n .test-item, .run-item { padding: 14px; }\n}\n\n@media (max-width: 480px) {\n .suite-icon {\n width: 40px;\n height: 40px;\n font-size: 18px;\n }\n\n .suite-info h1 { font-size: 16px; }\n\n .tab-badge { display: none; }\n\n .test-sequence { display: none; }\n}\n\n@media (hover: none) and (pointer: coarse) {\n .test-item:active, .run-item:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab { min-height: 48px; }\n .test-item, .run-item { min-height: 64px; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *, *::before, *::after {\n animation-duration: 0.01ms !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n@media print {\n .header-actions, .tabs-container, .keyboard-shortcuts {\n display: none !important;\n }\n}\n\n/* ===========================\n Tags UI\n =========================== */\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n}\n\n.tag-chip {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border: 1px solid #bfdbfe;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: #1d4ed8;\n}\n\n.tag-mini {\n display: inline-flex;\n align-items: center;\n padding: 2px 6px;\n background: #f1f5f9;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 500;\n color: #64748b;\n}\n\n.tag-more {\n font-size: 10px;\n color: #94a3b8;\n font-weight: 500;\n}\n\n/* Evaluation metrics row for Runs list */\n.run-eval-metrics {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n}\n\n.eval-metric {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.eval-metric.status {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.eval-metric.status.status-completed {\n background: #dcfce7;\n color: #166534;\n}\n\n.eval-metric.status.status-failed {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.eval-metric.status.status-running {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.eval-metric.status.status-pending {\n background: #fef3c7;\n color: #92400e;\n}\n\n.eval-metric.human {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #f59e0b;\n color: #92400e;\n}\n\n.eval-metric.human .eval-pending {\n font-size: 9px;\n color: #d97706;\n}\n\n.eval-metric.auto {\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n}\n\n.eval-metric.auto.high {\n background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);\n border: 1px solid #86efac;\n color: #166534;\n}\n\n.eval-metric.auto.medium {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n border: 1px solid #fcd34d;\n color: #92400e;\n}\n\n.eval-metric.auto.low {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n border: 1px solid #fca5a5;\n color: #991b1b;\n}\n\n.tag-cell {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.tag-chip-table {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 80px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* ===========================\n Analytics Tab\n =========================== */\n.analytics-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n/* Collapsible filters */\n.analytics-filters {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-bottom: 16px;\n box-shadow: var(--test-shadow-sm);\n overflow: hidden;\n}\n\n.analytics-filters.collapsed {\n margin-bottom: 12px;\n}\n\n.filters-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n cursor: pointer;\n user-select: none;\n transition: background 0.15s ease;\n}\n\n.filters-header:hover {\n background: var(--test-bg);\n}\n\n.filters-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.filters-title i {\n color: var(--test-primary);\n}\n\n.filter-summary {\n font-weight: 400;\n color: var(--test-text-muted);\n margin-left: 8px;\n}\n\n.filters-header > i {\n color: var(--test-text-muted);\n font-size: 12px;\n}\n\n.filters-content {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 12px 16px 16px 16px;\n border-top: 1px solid var(--test-border);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.filter-group 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.filter-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\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);\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 border-color: var(--test-primary);\n color: white;\n}\n\n.filter-btn.tag-btn {\n padding: 6px 12px;\n font-size: 12px;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn.tag-btn i.fa-check {\n font-size: 10px;\n}\n\n.filter-btn.tag-btn.all-tags-btn {\n font-weight: 600;\n}\n\n.filter-btn.tag-btn.all-tags-btn i {\n font-size: 11px;\n}\n\n.filter-hint {\n font-weight: 400;\n font-size: 10px;\n color: var(--test-primary);\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-filters {\n max-height: 120px;\n overflow-y: auto;\n}\n\n/* KPI Cards */\n.analytics-kpis {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.kpi-card {\n display: flex;\n align-items: center;\n gap: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\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: #eff6ff;\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 20px;\n}\n\n.kpi-icon.success {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-icon.info {\n background: #f0f9ff;\n color: #0ea5e9;\n}\n\n.kpi-icon.warning {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.kpi-content {\n flex: 1;\n min-width: 0;\n}\n\n.kpi-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n}\n\n.kpi-label {\n font-size: 12px;\n color: var(--test-text-secondary);\n margin-top: 2px;\n}\n\n.kpi-trend {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n font-size: 12px;\n font-weight: 600;\n margin-top: 4px;\n padding: 2px 8px;\n border-radius: 10px;\n background: #f1f5f9;\n color: var(--test-text-secondary);\n}\n\n.kpi-trend.trend-up {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.kpi-trend.trend-down {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n/* Analytics Table */\n.analytics-table-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.analytics-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.analytics-table-section h3 i {\n color: var(--test-primary);\n}\n\n.analytics-table-wrapper {\n overflow-x: auto;\n margin: 0 -24px;\n padding: 0 24px;\n}\n\n.analytics-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.analytics-table th {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.analytics-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.analytics-table tbody tr.clickable-row {\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.analytics-table tbody tr.clickable-row:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.status-completed { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-passed { background: #ecfdf5; color: var(--test-success); }\n.status-chip.status-failed { background: #fef2f2; color: var(--test-error); }\n.status-chip.status-error { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-running { background: #eff6ff; color: var(--test-primary); }\n.status-chip.status-pending { background: #f5f3ff; color: #8b5cf6; }\n.status-chip.status-cancelled { background: #f1f5f9; color: var(--test-disabled); }\n.status-chip.status-missing { background: #f1f5f9; color: var(--test-text-muted); }\n.status-chip.status-timeout { background: #fffbeb; color: var(--test-warning); }\n.status-chip.status-skipped { background: #f1f5f9; color: var(--test-disabled); }\n\n.pass-rate-cell {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 100px;\n}\n\n.pass-rate-bar {\n height: 6px;\n border-radius: 3px;\n background: var(--test-success);\n transition: width 0.3s ease;\n max-width: 60px;\n}\n\n.pass-rate-bar.medium { background: var(--test-warning); }\n.pass-rate-bar.low { background: var(--test-error); }\n\n/* Analytics Sub-navigation */\n.analytics-subnav {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 8px;\n margin-bottom: 20px;\n box-shadow: var(--test-shadow-sm);\n display: inline-flex;\n}\n\n.subnav-tabs {\n display: flex;\n gap: 4px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.subnav-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n border: none;\n border-radius: var(--test-radius-sm);\n background: transparent;\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.subnav-tab:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.subnav-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n box-shadow: var(--test-shadow-sm);\n}\n\n.subnav-tab i {\n font-size: 14px;\n}\n\n/* Matrix View */\n.matrix-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 16px;\n box-shadow: var(--test-shadow-sm);\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 280px);\n min-height: 300px;\n}\n\n.matrix-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 12px;\n margin-bottom: 12px;\n padding-bottom: 12px;\n border-bottom: 1px solid var(--test-border);\n flex-shrink: 0;\n}\n\n.matrix-header-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.matrix-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.matrix-header h3 i {\n color: var(--test-primary);\n}\n\n.matrix-run-count {\n font-size: 12px;\n color: var(--test-text-muted);\n font-weight: 500;\n}\n\n/* Matrix filter input */\n.matrix-filter-input {\n display: flex;\n align-items: center;\n gap: 8px;\n background: #f8fafc;\n border: 1px solid var(--test-border);\n border-radius: 6px;\n padding: 4px 10px;\n min-width: 180px;\n}\n\n.matrix-filter-input i.fa-search {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.matrix-filter-input .filter-input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 12px;\n color: var(--test-text);\n width: 100%;\n}\n\n.matrix-filter-input .filter-input::placeholder {\n color: #94a3b8;\n}\n\n.clear-filter-btn {\n border: none;\n background: none;\n padding: 2px 4px;\n cursor: pointer;\n color: #94a3b8;\n font-size: 10px;\n border-radius: 3px;\n transition: all 0.15s ease;\n}\n\n.clear-filter-btn:hover {\n background: #e2e8f0;\n color: #64748b;\n}\n\n/* Scrollable matrix container with fixed height */\n.matrix-scroll-container {\n flex: 1;\n overflow: auto;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n}\n\n.test-matrix {\n display: table;\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.test-matrix thead {\n display: table-header-group;\n}\n\n.test-matrix thead tr {\n display: table-row;\n}\n\n.test-matrix tbody {\n display: table-row-group;\n}\n\n.test-matrix tbody tr {\n display: table-row;\n cursor: pointer;\n transition: background-color 0.15s ease;\n}\n\n.test-matrix tbody tr:hover {\n background-color: rgba(59, 130, 246, 0.05);\n}\n\n.test-matrix tbody tr.row-selected {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix tbody tr.row-selected td {\n border-top: 1px solid rgba(59, 130, 246, 0.3);\n border-bottom: 1px solid rgba(59, 130, 246, 0.3);\n}\n\n.test-matrix tbody tr.row-selected .seq-cell,\n.test-matrix tbody tr.row-selected .test-name-cell {\n background-color: rgba(59, 130, 246, 0.12) !important;\n}\n\n.test-matrix tfoot {\n display: table-footer-group;\n}\n\n.test-matrix th,\n.test-matrix td {\n display: table-cell;\n border: 1px solid var(--test-border);\n padding: 8px 12px;\n text-align: center;\n vertical-align: middle;\n}\n\n.test-matrix th {\n background: var(--test-bg);\n font-weight: 600;\n font-size: 11px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n z-index: 10;\n border-bottom: 3px solid #475569 !important;\n}\n\n/* Sequence column - shared styles */\n.test-matrix .seq-header,\n.test-matrix .seq-cell {\n width: 36px;\n min-width: 36px;\n max-width: 36px;\n text-align: center;\n position: sticky;\n left: 0;\n font-size: 11px;\n color: #64748b;\n border-right: 1px solid var(--test-border);\n padding: 6px 4px !important;\n}\n\n/* Seq header - sticky top AND left, highest z-index */\n.test-matrix .seq-header {\n cursor: pointer;\n font-weight: 600;\n background: var(--test-bg);\n z-index: 12; /* Higher than other headers */\n top: 0;\n}\n\n/* Seq body cells - sticky left only, lower z-index */\n.test-matrix .seq-cell {\n background: var(--test-surface);\n z-index: 2;\n}\n\n.test-matrix .seq-header i {\n font-size: 9px;\n margin-left: 2px;\n opacity: 0.6;\n}\n\n.test-matrix .seq-header:hover {\n background: #f1f5f9;\n}\n\n.test-matrix .test-name-header {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-bg);\n z-index: 11;\n border-right: 2px solid var(--test-border);\n cursor: pointer;\n}\n\n.test-matrix .test-name-header i {\n font-size: 9px;\n margin-left: 4px;\n opacity: 0.6;\n}\n\n.test-matrix .test-name-header:hover {\n background: #f1f5f9;\n}\n\n.test-matrix .run-header {\n min-width: 120px;\n width: 120px;\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n/* Spacer column absorbs extra width */\n.test-matrix .spacer-header,\n.test-matrix .spacer-cell {\n width: 100%;\n min-width: 20px;\n background: var(--test-bg);\n border: none;\n}\n\n.test-matrix .spacer-cell {\n background: var(--test-surface);\n}\n\n.test-matrix .run-header:hover {\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-header-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.run-date {\n font-size: 12px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.run-pass-rate {\n font-size: 11px;\n font-weight: 700;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.run-pass-rate.high {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.run-pass-rate.medium {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.run-pass-rate.low {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.run-tags {\n display: flex;\n gap: 4px;\n}\n\n.tag-tiny {\n font-size: 9px;\n padding: 2px 6px;\n background: #eff6ff;\n color: var(--test-primary);\n border-radius: 8px;\n white-space: nowrap;\n max-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Matrix column header tags - emphasized */\n.run-tags-header {\n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n justify-content: center;\n margin-bottom: 4px;\n}\n\n.tag-chip-header {\n display: inline-block;\n padding: 3px 8px;\n background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);\n border: 1px solid #93c5fd;\n color: #1d4ed8;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n white-space: nowrap;\n max-width: 70px;\n overflow: hidden;\n text-overflow: ellipsis;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.tag-more-header {\n font-size: 9px;\n color: var(--test-text-secondary);\n padding: 2px 4px;\n}\n\n.test-matrix .test-name-cell {\n text-align: left;\n min-width: 150px;\n max-width: 500px;\n width: auto;\n position: sticky;\n left: 36px;\n background: var(--test-surface);\n z-index: 2;\n border-right: 2px solid var(--test-border);\n padding: 6px 10px !important;\n}\n\n.test-name {\n display: block;\n white-space: nowrap;\n font-weight: 500;\n color: var(--test-text);\n font-size: 12px;\n}\n\n.result-cell {\n position: relative;\n min-width: 120px;\n width: 120px;\n transition: var(--test-transition);\n}\n\n.result-cell.clickable {\n cursor: pointer;\n}\n\n.result-cell.clickable:hover {\n transform: scale(1.1);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n z-index: 5;\n}\n\n.result-cell i {\n font-size: 14px;\n}\n\n/* Completed cells have neutral white background - pills tell the story */\n.result-cell.cell-passed,\n.result-cell.cell-failed,\n.result-cell.cell-error,\n.result-cell.cell-timeout,\n.result-cell.cell-running,\n.result-cell.cell-pending {\n background: #ffffff;\n color: var(--test-text);\n}\n\n/* Skipped/not-run cells get hatched background */\n.result-cell.cell-skipped {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: var(--test-disabled);\n}\n\n.result-cell.cell-none {\n background: #f8fafc;\n color: var(--test-text-muted);\n}\n\n.cell-score {\n display: block;\n font-size: 10px;\n font-weight: 600;\n margin-top: 2px;\n}\n\n/* Matrix cell evaluation stack - shows multiple eval types horizontally */\n.cell-eval-stack {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex-wrap: nowrap;\n}\n\n.result-cell.multi-eval {\n min-width: 120px;\n width: auto;\n}\n\n/* Add timeout status icon */\n.cell-status.status-timeout {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-status.status-failed {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-status.status-error {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-status.status-skipped {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running {\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-status.status-pending {\n background: #f3e8ff;\n color: #7c3aed;\n}\n\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n background: #fef3c7;\n color: #d97706;\n font-size: 10px;\n}\n\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n background: #dbeafe;\n color: #1d4ed8;\n}\n\n.cell-auto.high {\n background: #dcfce7;\n color: #166534;\n}\n\n.cell-auto.medium {\n background: #fef3c7;\n color: #92400e;\n}\n\n.cell-auto.low {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.cell-none-indicator {\n color: var(--test-text-muted);\n opacity: 0.5;\n}\n\n.matrix-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n}\n\n.matrix-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Chart View\n =========================== */\n.chart-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.chart-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n flex-wrap: wrap;\n gap: 16px;\n margin-bottom: 20px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--test-border);\n}\n\n.chart-header h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.chart-header h3 i {\n color: var(--test-primary);\n}\n\n.chart-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.chart-legend .legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n padding: 4px 10px;\n border-radius: 12px;\n}\n\n.chart-legend .legend-item.chart-passed {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.chart-legend .legend-item.chart-failed {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.chart-legend .legend-item.chart-error {\n background: #fffbeb;\n color: var(--test-warning);\n}\n\n.chart-legend .legend-item.chart-skipped {\n background: #f1f5f9;\n color: var(--test-disabled);\n}\n\n.chart-container {\n min-height: 500px;\n position: relative;\n overflow: hidden;\n background: linear-gradient(135deg, #fafbff 0%, #f8fafc 100%);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.d3-chart {\n width: 100%;\n height: 500px;\n}\n\n.d3-chart svg {\n width: 100%;\n height: 100%;\n}\n\n/* D3 Chart Node Styles */\n.d3-chart .node {\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.d3-chart .node:hover {\n transform: scale(1.05);\n}\n\n.d3-chart .node-label {\n font-size: 11px;\n font-weight: 500;\n fill: var(--test-text);\n pointer-events: none;\n}\n\n.d3-chart .link {\n fill: none;\n stroke-opacity: 0.4;\n transition: stroke-opacity 0.2s ease;\n}\n\n.d3-chart .link:hover {\n stroke-opacity: 0.8;\n}\n\n.d3-chart .tooltip {\n position: absolute;\n padding: 10px 14px;\n background: rgba(30, 41, 59, 0.95);\n color: white;\n border-radius: 8px;\n font-size: 12px;\n pointer-events: none;\n z-index: 100;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);\n max-width: 250px;\n}\n\n.d3-chart .tooltip-title {\n font-weight: 600;\n margin-bottom: 4px;\n}\n\n.d3-chart .tooltip-value {\n opacity: 0.8;\n}\n\n.chart-info {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n color: var(--test-text-muted);\n padding: 12px;\n background: var(--test-bg);\n border-radius: var(--test-radius-sm);\n margin-top: 16px;\n}\n\n.chart-info i {\n color: var(--test-primary);\n}\n\n/* ===========================\n Compare Tab\n =========================== */\n.compare-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-selection {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 24px;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.compare-run-selector {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.compare-run-selector h4 {\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.run-selector-list {\n max-height: 200px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.run-selector-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.run-selector-item:hover {\n border-color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.run-selector-item.selected {\n border-color: var(--test-primary);\n background: #eff6ff;\n}\n\n.run-selector-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.selector-status {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.selector-content {\n flex: 1;\n min-width: 0;\n}\n\n.selector-date {\n font-size: 12px;\n font-weight: 500;\n color: var(--test-text);\n}\n\n.selector-rate {\n font-size: 11px;\n color: var(--test-text-secondary);\n}\n\n.selector-tags {\n display: flex;\n gap: 4px;\n flex-wrap: wrap;\n}\n\n.selected-run-preview {\n padding: 12px;\n background: #f8fafc;\n border-radius: var(--test-radius-sm);\n border: 1px solid var(--test-border);\n}\n\n.preview-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.preview-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n}\n\n.clear-btn {\n padding: 4px 8px;\n border: none;\n background: transparent;\n color: var(--test-error);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.clear-btn:hover { text-decoration: underline; }\n\n.preview-details {\n display: flex;\n justify-content: space-between;\n font-size: 12px;\n color: var(--test-text);\n}\n\n.preview-rate {\n font-weight: 600;\n color: var(--test-success);\n}\n\n.compare-vs {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n align-self: center;\n margin-top: 60px;\n}\n\n/* Compare Results */\n.compare-results {\n animation: fadeIn 0.3s ease-out;\n}\n\n.compare-summary {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.compare-summary-card {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 20px;\n box-shadow: var(--test-shadow-sm);\n text-align: center;\n}\n\n.compare-summary-card .summary-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n color: var(--test-text-muted);\n margin-bottom: 8px;\n}\n\n.compare-summary-card .summary-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.compare-summary-card .summary-value.positive { color: var(--test-success); }\n.compare-summary-card .summary-value.negative { color: var(--test-error); }\n\n.compare-summary-card.improved {\n border-left: 4px solid var(--test-success);\n}\n\n.compare-summary-card.improved .summary-value { color: var(--test-success); }\n\n.compare-summary-card.regressed {\n border-left: 4px solid var(--test-error);\n}\n\n.compare-summary-card.regressed .summary-value { color: var(--test-error); }\n\n/* Compare Table */\n.compare-table-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.compare-table-section h3 {\n margin: 0 0 16px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.compare-table-section h3 i {\n color: var(--test-primary);\n}\n\n.compare-table-wrapper {\n overflow-x: auto;\n}\n\n.compare-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.compare-table th {\n text-align: left;\n padding: 12px 16px;\n background: #f8fafc;\n border-bottom: 2px solid var(--test-border);\n font-weight: 600;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n font-size: 11px;\n letter-spacing: 0.5px;\n white-space: nowrap;\n}\n\n.compare-table td {\n padding: 14px 16px;\n border-bottom: 1px solid var(--test-border);\n color: var(--test-text);\n}\n\n.compare-table tbody tr.improved {\n background: rgba(16, 185, 129, 0.05);\n}\n\n.compare-table tbody tr.regressed {\n background: rgba(239, 68, 68, 0.05);\n}\n\n.test-name-cell {\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.positive { color: var(--test-success); }\n.negative { color: var(--test-error); }\n.muted { color: var(--test-text-muted); }\n\n.change-indicator {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.change-indicator.improved {\n background: #ecfdf5;\n color: var(--test-success);\n}\n\n.change-indicator.regressed {\n background: #fef2f2;\n color: var(--test-error);\n}\n\n.change-indicator.unchanged {\n background: #f1f5f9;\n color: var(--test-text-muted);\n}\n\n/* Compare Empty State */\n.compare-empty {\n text-align: center;\n padding: 60px 24px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n margin-top: 24px;\n}\n\n.compare-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: 0 auto 20px;\n}\n\n.compare-empty-icon i {\n font-size: 32px;\n color: var(--test-text-muted);\n}\n\n.compare-empty h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.compare-empty p {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 400px;\n margin: 0 auto;\n}\n\n/* Small empty state variant */\n.empty-state.small {\n padding: 32px 16px;\n}\n\n.empty-state.small p {\n margin: 0;\n}\n\n/* ===========================\n Responsive Analytics/Compare\n =========================== */\n@media (max-width: 1024px) {\n .compare-selection {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .compare-vs {\n margin: 0;\n align-self: center;\n justify-self: center;\n }\n\n .analytics-kpis {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .filter-buttons {\n flex-direction: column;\n }\n\n .filter-btn {\n width: 100%;\n text-align: center;\n }\n\n .analytics-kpis {\n grid-template-columns: 1fr;\n }\n\n .kpi-card {\n padding: 16px;\n }\n\n .kpi-value {\n font-size: 20px;\n }\n\n .compare-summary {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .analytics-table-wrapper,\n .compare-table-wrapper {\n margin: 0 -20px;\n padding: 0 20px;\n }\n\n .run-selector-list {\n max-height: 150px;\n }\n}\n\n@media (max-width: 480px) {\n .compare-summary {\n grid-template-columns: 1fr;\n }\n\n .compare-summary-card .summary-value {\n font-size: 20px;\n }\n\n .analytics-table th,\n .analytics-table td,\n .compare-table th,\n .compare-table td {\n padding: 10px 12px;\n font-size: 12px;\n }\n}\n\n/* ===========================\n Matrix Evaluation Indicators\n =========================== */\n\n/* Human Feedback Indicators */\n.cell-human {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-human.no-feedback {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-human.no-feedback i {\n font-size: 11px;\n}\n\n.cell-human.has-feedback {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-human.has-feedback i {\n font-size: 9px;\n}\n\n.cell-human.has-feedback .rating-value {\n font-weight: 700;\n font-size: 11px;\n}\n\n/* Human rating color coding: red \u22644, yellow 5-6, light-green 7-8, green 9-10 */\n.cell-human.rating-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-human.rating-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-human.rating-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-human.rating-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Auto Score Indicators */\n.cell-auto {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 3px;\n min-width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 10px;\n}\n\n.cell-auto.no-score {\n background: #f1f5f9;\n color: #94a3b8;\n}\n\n.cell-auto.no-score i {\n font-size: 11px;\n}\n\n.cell-auto.has-score {\n padding: 0 6px;\n border-radius: 12px;\n min-width: 36px;\n}\n\n.cell-auto.has-score i {\n font-size: 9px;\n}\n\n.cell-auto.has-score .score-value {\n font-weight: 700;\n font-size: 10px;\n}\n\n/* Auto score color coding (0-100%): red <50, yellow 50-69, light-green 70-84, green 85+ */\n.cell-auto.score-low {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-auto.score-medium {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-auto.score-good {\n background: #d1fae5;\n color: #059669;\n}\n\n.cell-auto.score-excellent {\n background: #dcfce7;\n color: #16a34a;\n}\n\n/* Status indicators in matrix cells */\n.cell-status {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n font-size: 11px;\n}\n\n.cell-status.status-passed {\n background: #dcfce7;\n color: #16a34a;\n}\n\n.cell-status.status-failed {\n background: #fee2e2;\n color: #dc2626;\n}\n\n.cell-status.status-error {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-timeout {\n background: #fef3c7;\n color: #d97706;\n}\n\n.cell-status.status-skipped,\n.cell-status.status-pending {\n background: #f1f5f9;\n color: #64748b;\n}\n\n.cell-status.status-running {\n background: #dbeafe;\n color: #2563eb;\n}\n\n/* Not-run / Skipped cells with hatch pattern */\n.result-cell.cell-not-run {\n background: repeating-linear-gradient(\n 45deg,\n #f8fafc,\n #f8fafc 4px,\n #e2e8f0 4px,\n #e2e8f0 8px\n );\n color: #94a3b8;\n}\n\n.result-cell.cell-not-run .cell-eval-stack {\n opacity: 0.6;\n}\n\n.cell-not-run-indicator {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n color: #94a3b8;\n font-size: 11px;\n}\n\n/* ===========================\n Matrix Totals Footer Row\n =========================== */\n.test-matrix tfoot {\n position: sticky;\n bottom: 0;\n z-index: 2;\n}\n\n.totals-row {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n border-top: 2px solid var(--test-border);\n}\n\n.totals-row td {\n padding: 10px 12px;\n font-weight: 600;\n}\n\n.totals-row .totals-label {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n font-size: 12px;\n color: var(--test-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.totals-row .totals-cell {\n background: linear-gradient(to bottom, #f8fafc, #f1f5f9);\n}\n\n.totals-stack {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n}\n\n.totals-status,\n.totals-human,\n.totals-auto {\n display: flex;\n align-items: center;\n gap: 4px;\n font-size: 11px;\n padding: 2px 8px;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.totals-status {\n background: #e0f2fe;\n color: #0369a1;\n}\n\n.totals-status .pass-count {\n font-weight: 700;\n}\n\n.totals-human {\n background: #fef3c7;\n color: #92400e;\n}\n\n.totals-human .avg-label {\n font-weight: 700;\n}\n\n.totals-human .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n\n.totals-auto {\n background: #dbeafe;\n color: #1e40af;\n}\n\n.totals-auto .avg-label {\n font-weight: 700;\n}\n\n.totals-auto .count-label {\n font-size: 10px;\n opacity: 0.8;\n}\n"] }]
|
|
3479
|
+
}], () => [{ 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 }], { chartContainer: [{
|
|
3459
3480
|
type: ViewChild,
|
|
3460
3481
|
args: ['chartContainer']
|
|
3461
3482
|
}], handleKeyboardShortcut: [{
|
|
3462
3483
|
type: HostListener,
|
|
3463
3484
|
args: ['document:keydown', ['$event']]
|
|
3464
3485
|
}] }); })();
|
|
3465
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestSuiteFormComponentExtended, { className: "TestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber:
|
|
3486
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestSuiteFormComponentExtended, { className: "TestSuiteFormComponentExtended", filePath: "src/lib/custom/Tests/test-suite-form.component.ts", lineNumber: 31 }); })();
|
|
3466
3487
|
export function LoadTestSuiteFormComponentExtended() { }
|
|
3467
3488
|
LoadTestSuiteFormComponentExtended();
|
|
3468
3489
|
//# sourceMappingURL=test-suite-form.component.js.map
|