lib-e2e-cypress-for-dummys-ts 0.8.0 → 0.9.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/README.md +1 -34
- package/dist/{chunk-FDMUIHDZ.js → chunk-CQEDHL7A.js} +1 -1
- package/dist/chunk-CQEDHL7A.js.map +1 -0
- package/dist/index.cjs +353 -736
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -140
- package/dist/index.d.ts +18 -140
- package/dist/index.js +355 -725
- package/dist/index.js.map +1 -1
- package/dist/selector-picker-JM5HID3Z.js +7 -0
- package/package.json +74 -81
- package/dist/chunk-FDMUIHDZ.js.map +0 -1
- package/dist/selector-picker-NKYFFFGK.js +0 -7
- /package/dist/{selector-picker-NKYFFFGK.js.map → selector-picker-JM5HID3Z.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -463,20 +463,15 @@ __export(index_exports, {
|
|
|
463
463
|
ACTIVE_SESSION_BREADCRUMB_KEY: () => ACTIVE_SESSION_BREADCRUMB_KEY,
|
|
464
464
|
AdvancedTestEditorElement: () => AdvancedTestEditorElement,
|
|
465
465
|
AdvancedTestTransformationService: () => AdvancedTestTransformationService,
|
|
466
|
-
CHAIN_METHODS: () => CHAIN_METHODS,
|
|
467
|
-
CYPRESS_COMPLETIONS: () => CYPRESS_COMPLETIONS,
|
|
468
|
-
CY_METHODS: () => CY_METHODS,
|
|
469
466
|
ConfigurationElement: () => ConfigurationElement,
|
|
470
467
|
DB_SCHEMA: () => DB_SCHEMA,
|
|
471
468
|
DB_STORE_NAMES: () => DB_STORE_NAMES,
|
|
472
|
-
DEFAULT_ISSUE_TRACKER_PROVIDER_ID: () => DEFAULT_ISSUE_TRACKER_PROVIDER_ID,
|
|
473
469
|
DEFAULT_RESUME_TTL_MINUTES: () => DEFAULT_RESUME_TTL_MINUTES,
|
|
474
470
|
DRAG_THRESHOLD: () => DRAG_THRESHOLD,
|
|
475
471
|
FilePreviewElement: () => FilePreviewElement,
|
|
476
472
|
HelpPanelElement: () => HelpPanelElement,
|
|
477
473
|
HttpMonitor: () => HttpMonitor,
|
|
478
474
|
INPUT_TYPES: () => INPUT_TYPES,
|
|
479
|
-
ISSUE_TRACKER_PROVIDERS: () => ISSUE_TRACKER_PROVIDERS,
|
|
480
475
|
LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES: () => LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES,
|
|
481
476
|
LOCALE_BY_LANG: () => LOCALE_BY_LANG,
|
|
482
477
|
LibE2eRecorderElement: () => LibE2eRecorderElement,
|
|
@@ -489,7 +484,6 @@ __export(index_exports, {
|
|
|
489
484
|
SelectorPickerElement: () => SelectorPickerElement,
|
|
490
485
|
Subject: () => Subject,
|
|
491
486
|
TOGGLE_MARGIN: () => TOGGLE_MARGIN,
|
|
492
|
-
TOP_LEVEL: () => TOP_LEVEL,
|
|
493
487
|
TestEditorElement: () => TestEditorElement,
|
|
494
488
|
TestPrevisualizerElement: () => TestPrevisualizerElement,
|
|
495
489
|
TransformationService: () => TransformationService,
|
|
@@ -498,14 +492,8 @@ __export(index_exports, {
|
|
|
498
492
|
advancedTestTransformationService: () => advancedTestTransformationService,
|
|
499
493
|
boxOffsetForDirection: () => boxOffsetForDirection,
|
|
500
494
|
boxTopLeftFor: () => boxTopLeftFor,
|
|
501
|
-
buildTicketComment: () => buildTicketComment,
|
|
502
|
-
buildTicketUrl: () => buildTicketUrl,
|
|
503
495
|
clampTogglePosition: () => clampTogglePosition,
|
|
504
|
-
createCodeEditor: () => createCodeEditor,
|
|
505
496
|
defaultTogglePosition: () => defaultTogglePosition,
|
|
506
|
-
filterCompletions: () => filterCompletions,
|
|
507
|
-
filterCypressCompletions: () => filterCypressCompletions,
|
|
508
|
-
findIssueTrackerProvider: () => findIssueTrackerProvider,
|
|
509
497
|
generateAlias: () => generateAlias,
|
|
510
498
|
inferAssertionCommand: () => inferAssertionCommand,
|
|
511
499
|
injectStyles: () => injectStyles,
|
|
@@ -517,7 +505,6 @@ __export(index_exports, {
|
|
|
517
505
|
makeSwalDraggableByContentId: () => makeSwalDraggableByContentId,
|
|
518
506
|
persistenceService: () => persistenceService,
|
|
519
507
|
resolveExpandDirection: () => resolveExpandDirection,
|
|
520
|
-
resolveTicketUrl: () => resolveTicketUrl,
|
|
521
508
|
selectTestsForExport: () => selectTestsForExport,
|
|
522
509
|
setSwal2DataCyAttribute: () => setSwal2DataCyAttribute,
|
|
523
510
|
showToast: () => showToast,
|
|
@@ -616,64 +603,6 @@ var ACTIVE_SESSION_BREADCRUMB_KEY = "e2e-active-session";
|
|
|
616
603
|
var RESUME_TTL_CONFIG_KEY = "resumeRecencyTtlMinutes";
|
|
617
604
|
var DEFAULT_RESUME_TTL_MINUTES = 30;
|
|
618
605
|
|
|
619
|
-
// src/models/issue-tracker.model.ts
|
|
620
|
-
var ISSUE_TRACKER_PROVIDERS = [
|
|
621
|
-
{
|
|
622
|
-
id: "jira",
|
|
623
|
-
labelKey: "CONFIG.ISSUE_TRACKER_PROVIDER_JIRA",
|
|
624
|
-
urlTemplate: "{baseUrl}/browse/{id}",
|
|
625
|
-
fields: [
|
|
626
|
-
{ key: "baseUrl", labelKey: "CONFIG.ISSUE_TRACKER_FIELD_BASEURL", placeholderKey: "CONFIG.ISSUE_TRACKER_PH_JIRA_BASEURL" }
|
|
627
|
-
],
|
|
628
|
-
idPattern: "^[A-Za-z][A-Za-z0-9_]+-\\d+$",
|
|
629
|
-
idPlaceholderKey: "SAVE_TEST.TICKET_PH_JIRA"
|
|
630
|
-
},
|
|
631
|
-
{
|
|
632
|
-
id: "azure-devops",
|
|
633
|
-
labelKey: "CONFIG.ISSUE_TRACKER_PROVIDER_AZURE",
|
|
634
|
-
urlTemplate: "https://dev.azure.com/{org}/{project}/_workitems/edit/{id}",
|
|
635
|
-
fields: [
|
|
636
|
-
{ key: "org", labelKey: "CONFIG.ISSUE_TRACKER_FIELD_ORG", placeholderKey: "CONFIG.ISSUE_TRACKER_PH_AZURE_ORG" },
|
|
637
|
-
{ key: "project", labelKey: "CONFIG.ISSUE_TRACKER_FIELD_PROJECT", placeholderKey: "CONFIG.ISSUE_TRACKER_PH_AZURE_PROJECT" }
|
|
638
|
-
],
|
|
639
|
-
idPattern: "^\\d+$",
|
|
640
|
-
idPlaceholderKey: "SAVE_TEST.TICKET_PH_AZURE"
|
|
641
|
-
},
|
|
642
|
-
{
|
|
643
|
-
id: "github",
|
|
644
|
-
labelKey: "CONFIG.ISSUE_TRACKER_PROVIDER_GITHUB",
|
|
645
|
-
urlTemplate: "https://github.com/{owner}/{repo}/issues/{id}",
|
|
646
|
-
fields: [
|
|
647
|
-
{ key: "owner", labelKey: "CONFIG.ISSUE_TRACKER_FIELD_OWNER", placeholderKey: "CONFIG.ISSUE_TRACKER_PH_GITHUB_OWNER" },
|
|
648
|
-
{ key: "repo", labelKey: "CONFIG.ISSUE_TRACKER_FIELD_REPO", placeholderKey: "CONFIG.ISSUE_TRACKER_PH_GITHUB_REPO" }
|
|
649
|
-
],
|
|
650
|
-
idPattern: "^\\d+$",
|
|
651
|
-
idPlaceholderKey: "SAVE_TEST.TICKET_PH_GITHUB"
|
|
652
|
-
},
|
|
653
|
-
{
|
|
654
|
-
id: "trello",
|
|
655
|
-
labelKey: "CONFIG.ISSUE_TRACKER_PROVIDER_TRELLO",
|
|
656
|
-
urlTemplate: "https://trello.com/c/{id}",
|
|
657
|
-
fields: [],
|
|
658
|
-
idPattern: "^[A-Za-z0-9]+$",
|
|
659
|
-
idPlaceholderKey: "SAVE_TEST.TICKET_PH_TRELLO"
|
|
660
|
-
},
|
|
661
|
-
{
|
|
662
|
-
id: "custom",
|
|
663
|
-
labelKey: "CONFIG.ISSUE_TRACKER_PROVIDER_CUSTOM",
|
|
664
|
-
urlTemplate: "{template}",
|
|
665
|
-
fields: [
|
|
666
|
-
{ key: "template", labelKey: "CONFIG.ISSUE_TRACKER_FIELD_TEMPLATE", placeholderKey: "CONFIG.ISSUE_TRACKER_PH_CUSTOM_TEMPLATE" }
|
|
667
|
-
],
|
|
668
|
-
idPattern: ".*",
|
|
669
|
-
idPlaceholderKey: "SAVE_TEST.TICKET_PH_CUSTOM"
|
|
670
|
-
}
|
|
671
|
-
];
|
|
672
|
-
var DEFAULT_ISSUE_TRACKER_PROVIDER_ID = "custom";
|
|
673
|
-
function findIssueTrackerProvider(id) {
|
|
674
|
-
return ISSUE_TRACKER_PROVIDERS.find((p) => p.id === id);
|
|
675
|
-
}
|
|
676
|
-
|
|
677
606
|
// src/utils/subject.ts
|
|
678
607
|
var Subject = class {
|
|
679
608
|
_value;
|
|
@@ -719,13 +648,9 @@ var I18N_ES = {
|
|
|
719
648
|
REMOVE_TAG_TITLE: "Quitar",
|
|
720
649
|
NOTES_LABEL: "Descripci\xF3n / Notas (opcional):",
|
|
721
650
|
NOTES_PLACEHOLDER: "Qu\xE9 valida este test, condiciones previas, etc.",
|
|
722
|
-
TICKET_LABEL: "Ticket (opcional):",
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
TICKET_PH_GITHUB: "ej. 42",
|
|
726
|
-
TICKET_PH_TRELLO: "ej. aBc123",
|
|
727
|
-
TICKET_PH_CUSTOM: "id del ticket",
|
|
728
|
-
TICKET_INVALID: "El id del ticket no coincide con el formato esperado del gestor seleccionado."
|
|
651
|
+
TICKET_LABEL: "Ticket / Issue (opcional):",
|
|
652
|
+
TICKET_PLACEHOLDER: "Ej: PROJ-123, #42",
|
|
653
|
+
TICKET_WARN: "ID no v\xE1lido para el proveedor configurado (se guardar\xE1 igualmente)"
|
|
729
654
|
},
|
|
730
655
|
TEST_EDITOR: {
|
|
731
656
|
NO_TAGS: "Sin etiquetas",
|
|
@@ -741,7 +666,9 @@ var I18N_ES = {
|
|
|
741
666
|
NO_TESTS: "No hay tests guardados",
|
|
742
667
|
DELETE_TITLE: "Eliminar",
|
|
743
668
|
GROUP_BY_TICKET: "\u{1F3AB} Agrupar por ticket",
|
|
744
|
-
|
|
669
|
+
UNGROUP_TICKET: "\u{1F3AB} Desagrupar",
|
|
670
|
+
NO_TICKET: "Sin ticket",
|
|
671
|
+
TICKET_LINK_TITLE: "Abrir ticket"
|
|
745
672
|
},
|
|
746
673
|
CONFIG: {
|
|
747
674
|
LANG_SECTION: "\u{1F310} Idioma",
|
|
@@ -800,26 +727,12 @@ var I18N_ES = {
|
|
|
800
727
|
WIDGET_POSITION_HINT: "Arrastra el bot\xF3n de grabar para moverlo donde no estorbe. Se recuerda su posici\xF3n.",
|
|
801
728
|
WIDGET_POSITION_RESET_BTN: "\u21BA Restablecer posici\xF3n",
|
|
802
729
|
WIDGET_POSITION_RESET_DONE: "\u2713 Posici\xF3n restablecida",
|
|
803
|
-
ISSUE_TRACKER_SECTION: "\u{1F3AB}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
ISSUE_TRACKER_PROVIDER_TRELLO: "Trello",
|
|
810
|
-
ISSUE_TRACKER_PROVIDER_CUSTOM: "Personalizado",
|
|
811
|
-
ISSUE_TRACKER_FIELD_BASEURL: "URL base",
|
|
812
|
-
ISSUE_TRACKER_FIELD_ORG: "Organizaci\xF3n",
|
|
813
|
-
ISSUE_TRACKER_FIELD_PROJECT: "Proyecto",
|
|
814
|
-
ISSUE_TRACKER_FIELD_OWNER: "Propietario",
|
|
815
|
-
ISSUE_TRACKER_FIELD_REPO: "Repositorio",
|
|
816
|
-
ISSUE_TRACKER_FIELD_TEMPLATE: "Plantilla de URL (debe contener {id})",
|
|
817
|
-
ISSUE_TRACKER_PH_JIRA_BASEURL: "https://tu-org.atlassian.net",
|
|
818
|
-
ISSUE_TRACKER_PH_AZURE_ORG: "organizaci\xF3n",
|
|
819
|
-
ISSUE_TRACKER_PH_AZURE_PROJECT: "proyecto",
|
|
820
|
-
ISSUE_TRACKER_PH_GITHUB_OWNER: "propietario",
|
|
821
|
-
ISSUE_TRACKER_PH_GITHUB_REPO: "repositorio",
|
|
822
|
-
ISSUE_TRACKER_PH_CUSTOM_TEMPLATE: "https://tracker.example.com/{id}"
|
|
730
|
+
ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue tracker",
|
|
731
|
+
ISSUE_TRACKER_TITLE: "Vincular tests a tickets",
|
|
732
|
+
ISSUE_TRACKER_SUB: "A\xF1ade un ID de ticket al guardar y genera un enlace clickable en el listado.",
|
|
733
|
+
ISSUE_TRACKER_PROVIDER: "Proveedor",
|
|
734
|
+
ISSUE_TRACKER_BASE_URL: "URL base",
|
|
735
|
+
ISSUE_TRACKER_BASE_URL_PH: "Ej: https://miproyecto.atlassian.net"
|
|
823
736
|
},
|
|
824
737
|
SELECTOR_PICKER: {
|
|
825
738
|
TITLE: "Selecciona un elemento del DOM",
|
|
@@ -1022,13 +935,9 @@ var I18N_EN = {
|
|
|
1022
935
|
REMOVE_TAG_TITLE: "Remove",
|
|
1023
936
|
NOTES_LABEL: "Description / Notes (optional):",
|
|
1024
937
|
NOTES_PLACEHOLDER: "What this test validates, preconditions, etc.",
|
|
1025
|
-
TICKET_LABEL: "Ticket (optional):",
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
TICKET_PH_GITHUB: "e.g. 42",
|
|
1029
|
-
TICKET_PH_TRELLO: "e.g. aBc123",
|
|
1030
|
-
TICKET_PH_CUSTOM: "ticket id",
|
|
1031
|
-
TICKET_INVALID: "The ticket id does not match the expected format for the selected tracker."
|
|
938
|
+
TICKET_LABEL: "Ticket / Issue (optional):",
|
|
939
|
+
TICKET_PLACEHOLDER: "E.g.: PROJ-123, #42",
|
|
940
|
+
TICKET_WARN: "Invalid ID for the configured provider (will be saved anyway)"
|
|
1032
941
|
},
|
|
1033
942
|
TEST_EDITOR: {
|
|
1034
943
|
NO_TAGS: "No tags",
|
|
@@ -1044,7 +953,9 @@ var I18N_EN = {
|
|
|
1044
953
|
NO_TESTS: "No saved tests",
|
|
1045
954
|
DELETE_TITLE: "Delete",
|
|
1046
955
|
GROUP_BY_TICKET: "\u{1F3AB} Group by ticket",
|
|
1047
|
-
|
|
956
|
+
UNGROUP_TICKET: "\u{1F3AB} Ungroup",
|
|
957
|
+
NO_TICKET: "No ticket",
|
|
958
|
+
TICKET_LINK_TITLE: "Open ticket"
|
|
1048
959
|
},
|
|
1049
960
|
CONFIG: {
|
|
1050
961
|
LANG_SECTION: "\u{1F310} Language",
|
|
@@ -1104,25 +1015,11 @@ var I18N_EN = {
|
|
|
1104
1015
|
WIDGET_POSITION_RESET_BTN: "\u21BA Reset position",
|
|
1105
1016
|
WIDGET_POSITION_RESET_DONE: "\u2713 Position reset",
|
|
1106
1017
|
ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue tracker",
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
ISSUE_TRACKER_PROVIDER_TRELLO: "Trello",
|
|
1113
|
-
ISSUE_TRACKER_PROVIDER_CUSTOM: "Custom",
|
|
1114
|
-
ISSUE_TRACKER_FIELD_BASEURL: "Base URL",
|
|
1115
|
-
ISSUE_TRACKER_FIELD_ORG: "Organization",
|
|
1116
|
-
ISSUE_TRACKER_FIELD_PROJECT: "Project",
|
|
1117
|
-
ISSUE_TRACKER_FIELD_OWNER: "Owner",
|
|
1118
|
-
ISSUE_TRACKER_FIELD_REPO: "Repository",
|
|
1119
|
-
ISSUE_TRACKER_FIELD_TEMPLATE: "URL template (must contain {id})",
|
|
1120
|
-
ISSUE_TRACKER_PH_JIRA_BASEURL: "https://your-org.atlassian.net",
|
|
1121
|
-
ISSUE_TRACKER_PH_AZURE_ORG: "organization",
|
|
1122
|
-
ISSUE_TRACKER_PH_AZURE_PROJECT: "project",
|
|
1123
|
-
ISSUE_TRACKER_PH_GITHUB_OWNER: "owner",
|
|
1124
|
-
ISSUE_TRACKER_PH_GITHUB_REPO: "repository",
|
|
1125
|
-
ISSUE_TRACKER_PH_CUSTOM_TEMPLATE: "https://tracker.example.com/{id}"
|
|
1018
|
+
ISSUE_TRACKER_TITLE: "Link tests to tickets",
|
|
1019
|
+
ISSUE_TRACKER_SUB: "Add a ticket ID when saving and generate a clickable link in the test list.",
|
|
1020
|
+
ISSUE_TRACKER_PROVIDER: "Provider",
|
|
1021
|
+
ISSUE_TRACKER_BASE_URL: "Base URL",
|
|
1022
|
+
ISSUE_TRACKER_BASE_URL_PH: "E.g.: https://myproject.atlassian.net"
|
|
1126
1023
|
},
|
|
1127
1024
|
SELECTOR_PICKER: {
|
|
1128
1025
|
TITLE: "Select a DOM element",
|
|
@@ -1325,13 +1222,10 @@ var I18N_FR = {
|
|
|
1325
1222
|
REMOVE_TAG_TITLE: "Retirer",
|
|
1326
1223
|
NOTES_LABEL: "Description / Notes (optionnel) :",
|
|
1327
1224
|
NOTES_PLACEHOLDER: "Ce que ce test valide, conditions pr\xE9alables, etc.",
|
|
1328
|
-
TICKET_LABEL: "Ticket (optionnel) :",
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
TICKET_PH_TRELLO: "p. ex. aBc123",
|
|
1333
|
-
TICKET_PH_CUSTOM: "id du ticket",
|
|
1334
|
-
TICKET_INVALID: "L'id du ticket ne correspond pas au format attendu par le gestionnaire s\xE9lectionn\xE9."
|
|
1225
|
+
TICKET_LABEL: "Ticket / Issue (optionnel) :",
|
|
1226
|
+
TICKET_PLACEHOLDER: "Ex : PROJ-123, #42",
|
|
1227
|
+
TICKET_WARN: "ID non valide pour le fournisseur configur\xE9 (sera enregistr\xE9 quand m\xEAme)"
|
|
1228
|
+
// TODO: translate
|
|
1335
1229
|
},
|
|
1336
1230
|
TEST_EDITOR: {
|
|
1337
1231
|
NO_TAGS: "Sans \xE9tiquettes",
|
|
@@ -1347,7 +1241,9 @@ var I18N_FR = {
|
|
|
1347
1241
|
NO_TESTS: "Aucun test enregistr\xE9",
|
|
1348
1242
|
DELETE_TITLE: "Supprimer",
|
|
1349
1243
|
GROUP_BY_TICKET: "\u{1F3AB} Grouper par ticket",
|
|
1350
|
-
|
|
1244
|
+
UNGROUP_TICKET: "\u{1F3AB} D\xE9grouper",
|
|
1245
|
+
NO_TICKET: "Sans ticket",
|
|
1246
|
+
TICKET_LINK_TITLE: "Ouvrir le ticket"
|
|
1351
1247
|
},
|
|
1352
1248
|
CONFIG: {
|
|
1353
1249
|
LANG_SECTION: "\u{1F310} Langue",
|
|
@@ -1407,25 +1303,11 @@ var I18N_FR = {
|
|
|
1407
1303
|
WIDGET_POSITION_RESET_BTN: "\u21BA R\xE9initialiser la position",
|
|
1408
1304
|
WIDGET_POSITION_RESET_DONE: "\u2713 Position r\xE9initialis\xE9e",
|
|
1409
1305
|
ISSUE_TRACKER_SECTION: "\u{1F3AB} Gestionnaire de tickets",
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
ISSUE_TRACKER_PROVIDER_TRELLO: "Trello",
|
|
1416
|
-
ISSUE_TRACKER_PROVIDER_CUSTOM: "Personnalis\xE9",
|
|
1417
|
-
ISSUE_TRACKER_FIELD_BASEURL: "URL de base",
|
|
1418
|
-
ISSUE_TRACKER_FIELD_ORG: "Organisation",
|
|
1419
|
-
ISSUE_TRACKER_FIELD_PROJECT: "Projet",
|
|
1420
|
-
ISSUE_TRACKER_FIELD_OWNER: "Propri\xE9taire",
|
|
1421
|
-
ISSUE_TRACKER_FIELD_REPO: "D\xE9p\xF4t",
|
|
1422
|
-
ISSUE_TRACKER_FIELD_TEMPLATE: "Mod\xE8le d'URL (doit contenir {id})",
|
|
1423
|
-
ISSUE_TRACKER_PH_JIRA_BASEURL: "https://votre-org.atlassian.net",
|
|
1424
|
-
ISSUE_TRACKER_PH_AZURE_ORG: "organisation",
|
|
1425
|
-
ISSUE_TRACKER_PH_AZURE_PROJECT: "projet",
|
|
1426
|
-
ISSUE_TRACKER_PH_GITHUB_OWNER: "propri\xE9taire",
|
|
1427
|
-
ISSUE_TRACKER_PH_GITHUB_REPO: "d\xE9p\xF4t",
|
|
1428
|
-
ISSUE_TRACKER_PH_CUSTOM_TEMPLATE: "https://tracker.example.com/{id}"
|
|
1306
|
+
ISSUE_TRACKER_TITLE: "Lier les tests aux tickets",
|
|
1307
|
+
ISSUE_TRACKER_SUB: "Ajoutez un ID de ticket lors de l'enregistrement et g\xE9n\xE9rez un lien cliquable.",
|
|
1308
|
+
ISSUE_TRACKER_PROVIDER: "Fournisseur",
|
|
1309
|
+
ISSUE_TRACKER_BASE_URL: "URL de base",
|
|
1310
|
+
ISSUE_TRACKER_BASE_URL_PH: "Ex : https://monprojet.atlassian.net"
|
|
1429
1311
|
},
|
|
1430
1312
|
SELECTOR_PICKER: {
|
|
1431
1313
|
TITLE: "S\xE9lectionnez un \xE9l\xE9ment du DOM",
|
|
@@ -1629,13 +1511,10 @@ var I18N_IT = {
|
|
|
1629
1511
|
REMOVE_TAG_TITLE: "Rimuovi",
|
|
1630
1512
|
NOTES_LABEL: "Descrizione / Note (opzionale):",
|
|
1631
1513
|
NOTES_PLACEHOLDER: "Cosa valida questo test, condizioni preliminari, ecc.",
|
|
1632
|
-
TICKET_LABEL: "Ticket (opzionale):",
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
TICKET_PH_TRELLO: "es. aBc123",
|
|
1637
|
-
TICKET_PH_CUSTOM: "id del ticket",
|
|
1638
|
-
TICKET_INVALID: "L'id del ticket non corrisponde al formato previsto dal gestore selezionato."
|
|
1514
|
+
TICKET_LABEL: "Ticket / Issue (opzionale):",
|
|
1515
|
+
TICKET_PLACEHOLDER: "Es: PROJ-123, #42",
|
|
1516
|
+
TICKET_WARN: "ID non valido per il provider configurato (verr\xE0 salvato comunque)"
|
|
1517
|
+
// TODO: translate
|
|
1639
1518
|
},
|
|
1640
1519
|
TEST_EDITOR: {
|
|
1641
1520
|
NO_TAGS: "Nessuna etichetta",
|
|
@@ -1651,7 +1530,9 @@ var I18N_IT = {
|
|
|
1651
1530
|
NO_TESTS: "Nessun test salvato",
|
|
1652
1531
|
DELETE_TITLE: "Elimina",
|
|
1653
1532
|
GROUP_BY_TICKET: "\u{1F3AB} Raggruppa per ticket",
|
|
1654
|
-
|
|
1533
|
+
UNGROUP_TICKET: "\u{1F3AB} Separa",
|
|
1534
|
+
NO_TICKET: "Senza ticket",
|
|
1535
|
+
TICKET_LINK_TITLE: "Apri ticket"
|
|
1655
1536
|
},
|
|
1656
1537
|
CONFIG: {
|
|
1657
1538
|
LANG_SECTION: "\u{1F310} Lingua",
|
|
@@ -1710,26 +1591,12 @@ var I18N_IT = {
|
|
|
1710
1591
|
WIDGET_POSITION_HINT: "Trascina il pulsante di registrazione per spostarlo. La posizione viene ricordata.",
|
|
1711
1592
|
WIDGET_POSITION_RESET_BTN: "\u21BA Reimposta posizione",
|
|
1712
1593
|
WIDGET_POSITION_RESET_DONE: "\u2713 Posizione reimpostata",
|
|
1713
|
-
ISSUE_TRACKER_SECTION: "\u{1F3AB}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
ISSUE_TRACKER_PROVIDER_TRELLO: "Trello",
|
|
1720
|
-
ISSUE_TRACKER_PROVIDER_CUSTOM: "Personalizzato",
|
|
1721
|
-
ISSUE_TRACKER_FIELD_BASEURL: "URL di base",
|
|
1722
|
-
ISSUE_TRACKER_FIELD_ORG: "Organizzazione",
|
|
1723
|
-
ISSUE_TRACKER_FIELD_PROJECT: "Progetto",
|
|
1724
|
-
ISSUE_TRACKER_FIELD_OWNER: "Proprietario",
|
|
1725
|
-
ISSUE_TRACKER_FIELD_REPO: "Repository",
|
|
1726
|
-
ISSUE_TRACKER_FIELD_TEMPLATE: "Modello di URL (deve contenere {id})",
|
|
1727
|
-
ISSUE_TRACKER_PH_JIRA_BASEURL: "https://tua-org.atlassian.net",
|
|
1728
|
-
ISSUE_TRACKER_PH_AZURE_ORG: "organizzazione",
|
|
1729
|
-
ISSUE_TRACKER_PH_AZURE_PROJECT: "progetto",
|
|
1730
|
-
ISSUE_TRACKER_PH_GITHUB_OWNER: "proprietario",
|
|
1731
|
-
ISSUE_TRACKER_PH_GITHUB_REPO: "repository",
|
|
1732
|
-
ISSUE_TRACKER_PH_CUSTOM_TEMPLATE: "https://tracker.example.com/{id}"
|
|
1594
|
+
ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue tracker",
|
|
1595
|
+
ISSUE_TRACKER_TITLE: "Collega i test ai ticket",
|
|
1596
|
+
ISSUE_TRACKER_SUB: "Aggiungi un ID ticket al salvataggio e genera un link cliccabile nell'elenco.",
|
|
1597
|
+
ISSUE_TRACKER_PROVIDER: "Provider",
|
|
1598
|
+
ISSUE_TRACKER_BASE_URL: "URL base",
|
|
1599
|
+
ISSUE_TRACKER_BASE_URL_PH: "Es: https://mioprogetto.atlassian.net"
|
|
1733
1600
|
},
|
|
1734
1601
|
SELECTOR_PICKER: {
|
|
1735
1602
|
TITLE: "Seleziona un elemento DOM",
|
|
@@ -1933,13 +1800,10 @@ var I18N_DE = {
|
|
|
1933
1800
|
REMOVE_TAG_TITLE: "Entfernen",
|
|
1934
1801
|
NOTES_LABEL: "Beschreibung / Notizen (optional):",
|
|
1935
1802
|
NOTES_PLACEHOLDER: "Was dieser Test validiert, Voraussetzungen usw.",
|
|
1936
|
-
TICKET_LABEL: "Ticket (optional):",
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
TICKET_PH_TRELLO: "z. B. aBc123",
|
|
1941
|
-
TICKET_PH_CUSTOM: "Ticket-ID",
|
|
1942
|
-
TICKET_INVALID: "Die Ticket-ID entspricht nicht dem erwarteten Format des ausgew\xE4hlten Trackers."
|
|
1803
|
+
TICKET_LABEL: "Ticket / Issue (optional):",
|
|
1804
|
+
TICKET_PLACEHOLDER: "Z. B.: PROJ-123, #42",
|
|
1805
|
+
TICKET_WARN: "Ung\xFCltige ID f\xFCr den konfigurierten Anbieter (wird trotzdem gespeichert)"
|
|
1806
|
+
// TODO: translate
|
|
1943
1807
|
},
|
|
1944
1808
|
TEST_EDITOR: {
|
|
1945
1809
|
NO_TAGS: "Keine Tags",
|
|
@@ -1955,7 +1819,9 @@ var I18N_DE = {
|
|
|
1955
1819
|
NO_TESTS: "Keine gespeicherten Tests",
|
|
1956
1820
|
DELETE_TITLE: "L\xF6schen",
|
|
1957
1821
|
GROUP_BY_TICKET: "\u{1F3AB} Nach Ticket gruppieren",
|
|
1958
|
-
|
|
1822
|
+
UNGROUP_TICKET: "\u{1F3AB} Gruppierung aufheben",
|
|
1823
|
+
NO_TICKET: "Kein Ticket",
|
|
1824
|
+
TICKET_LINK_TITLE: "Ticket \xF6ffnen"
|
|
1959
1825
|
},
|
|
1960
1826
|
CONFIG: {
|
|
1961
1827
|
LANG_SECTION: "\u{1F310} Sprache",
|
|
@@ -2015,25 +1881,11 @@ var I18N_DE = {
|
|
|
2015
1881
|
WIDGET_POSITION_RESET_BTN: "\u21BA Position zur\xFCcksetzen",
|
|
2016
1882
|
WIDGET_POSITION_RESET_DONE: "\u2713 Position zur\xFCckgesetzt",
|
|
2017
1883
|
ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue-Tracker",
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
ISSUE_TRACKER_PROVIDER_TRELLO: "Trello",
|
|
2024
|
-
ISSUE_TRACKER_PROVIDER_CUSTOM: "Benutzerdefiniert",
|
|
2025
|
-
ISSUE_TRACKER_FIELD_BASEURL: "Basis-URL",
|
|
2026
|
-
ISSUE_TRACKER_FIELD_ORG: "Organisation",
|
|
2027
|
-
ISSUE_TRACKER_FIELD_PROJECT: "Projekt",
|
|
2028
|
-
ISSUE_TRACKER_FIELD_OWNER: "Eigent\xFCmer",
|
|
2029
|
-
ISSUE_TRACKER_FIELD_REPO: "Repository",
|
|
2030
|
-
ISSUE_TRACKER_FIELD_TEMPLATE: "URL-Vorlage (muss {id} enthalten)",
|
|
2031
|
-
ISSUE_TRACKER_PH_JIRA_BASEURL: "https://ihre-org.atlassian.net",
|
|
2032
|
-
ISSUE_TRACKER_PH_AZURE_ORG: "Organisation",
|
|
2033
|
-
ISSUE_TRACKER_PH_AZURE_PROJECT: "Projekt",
|
|
2034
|
-
ISSUE_TRACKER_PH_GITHUB_OWNER: "Eigent\xFCmer",
|
|
2035
|
-
ISSUE_TRACKER_PH_GITHUB_REPO: "Repository",
|
|
2036
|
-
ISSUE_TRACKER_PH_CUSTOM_TEMPLATE: "https://tracker.example.com/{id}"
|
|
1884
|
+
ISSUE_TRACKER_TITLE: "Tests mit Tickets verkn\xFCpfen",
|
|
1885
|
+
ISSUE_TRACKER_SUB: "F\xFCge beim Speichern eine Ticket-ID hinzu und erstelle einen klickbaren Link.",
|
|
1886
|
+
ISSUE_TRACKER_PROVIDER: "Anbieter",
|
|
1887
|
+
ISSUE_TRACKER_BASE_URL: "Basis-URL",
|
|
1888
|
+
ISSUE_TRACKER_BASE_URL_PH: "Z. B.: https://meinprojekt.atlassian.net"
|
|
2037
1889
|
},
|
|
2038
1890
|
SELECTOR_PICKER: {
|
|
2039
1891
|
TITLE: "DOM-Element ausw\xE4hlen",
|
|
@@ -2402,6 +2254,7 @@ var RecordingService = class {
|
|
|
2402
2254
|
}
|
|
2403
2255
|
// ── Public API ────────────────────────────────────────────────────────────
|
|
2404
2256
|
startRecording() {
|
|
2257
|
+
this.clearCommands();
|
|
2405
2258
|
this.sessionId = createSessionId();
|
|
2406
2259
|
this.startedAt = Date.now();
|
|
2407
2260
|
this.isPaused$.next(false);
|
|
@@ -2751,6 +2604,13 @@ var RecordingService = class {
|
|
|
2751
2604
|
}
|
|
2752
2605
|
return;
|
|
2753
2606
|
}
|
|
2607
|
+
if (!this.isInteractiveElement(target)) {
|
|
2608
|
+
const interactive = target.closest(
|
|
2609
|
+
'button,a,input,select,textarea,label,summary,mat-option,[role="button"],[role="link"],[role="menuitem"],[role="option"],[role="tab"]'
|
|
2610
|
+
);
|
|
2611
|
+
if (!interactive) return;
|
|
2612
|
+
target = interactive;
|
|
2613
|
+
}
|
|
2754
2614
|
}
|
|
2755
2615
|
const tag = target.tagName.toLowerCase();
|
|
2756
2616
|
if (tag === "input" || tag === "textarea" || tag === "select") {
|
|
@@ -2783,6 +2643,10 @@ var RecordingService = class {
|
|
|
2783
2643
|
this.handleMatOptionClick(target, selector);
|
|
2784
2644
|
return;
|
|
2785
2645
|
}
|
|
2646
|
+
if (!selector) {
|
|
2647
|
+
this.selectorNotFound$.next({ target, action: "click" });
|
|
2648
|
+
return;
|
|
2649
|
+
}
|
|
2786
2650
|
this.addGenericCommand({
|
|
2787
2651
|
selector,
|
|
2788
2652
|
action: (s) => `cy.get('${s}').click()`
|
|
@@ -2905,42 +2769,6 @@ var RecordingService = class {
|
|
|
2905
2769
|
|
|
2906
2770
|
// src/services/persistence.service.ts
|
|
2907
2771
|
var import_idb = require("idb");
|
|
2908
|
-
|
|
2909
|
-
// src/utils/ticket.utils.ts
|
|
2910
|
-
function buildTicketUrl(provider, params, id) {
|
|
2911
|
-
const ticketId = (id ?? "").trim();
|
|
2912
|
-
if (!provider || !ticketId) return null;
|
|
2913
|
-
let url = provider.urlTemplate;
|
|
2914
|
-
for (const field of provider.fields) {
|
|
2915
|
-
const value = (params?.[field.key] ?? "").trim().replace(/\/+$/, "");
|
|
2916
|
-
if (!value) return null;
|
|
2917
|
-
url = url.split(`{${field.key}}`).join(value);
|
|
2918
|
-
}
|
|
2919
|
-
url = url.split("{id}").join(encodeURIComponent(ticketId));
|
|
2920
|
-
if (url.includes("{") || url.includes("}")) return null;
|
|
2921
|
-
return toSafeHttpUrl(url);
|
|
2922
|
-
}
|
|
2923
|
-
function resolveTicketUrl(providerId, allParams, ticketId) {
|
|
2924
|
-
const id = (ticketId ?? "").trim();
|
|
2925
|
-
if (!id) return null;
|
|
2926
|
-
const provider = findIssueTrackerProvider(providerId);
|
|
2927
|
-
if (!provider) return null;
|
|
2928
|
-
return buildTicketUrl(provider, allParams?.[providerId] ?? {}, id);
|
|
2929
|
-
}
|
|
2930
|
-
function toSafeHttpUrl(candidate) {
|
|
2931
|
-
try {
|
|
2932
|
-
const parsed = new URL(candidate);
|
|
2933
|
-
return parsed.protocol === "http:" || parsed.protocol === "https:" ? parsed.href : null;
|
|
2934
|
-
} catch {
|
|
2935
|
-
return null;
|
|
2936
|
-
}
|
|
2937
|
-
}
|
|
2938
|
-
function buildTicketComment(id, url) {
|
|
2939
|
-
const ticketId = (id ?? "").trim();
|
|
2940
|
-
return url ? `// ${ticketId} \u2014 ${url}` : `// ${ticketId}`;
|
|
2941
|
-
}
|
|
2942
|
-
|
|
2943
|
-
// src/services/persistence.service.ts
|
|
2944
2772
|
var ACTIVE_SESSION_ID = 1;
|
|
2945
2773
|
var PersistenceService = class {
|
|
2946
2774
|
// dbName is overridable so tests can use unique names for isolation.
|
|
@@ -2995,28 +2823,12 @@ var PersistenceService = class {
|
|
|
2995
2823
|
if (!record) return null;
|
|
2996
2824
|
const commands = await this.getCommandStrings(testId);
|
|
2997
2825
|
const interceptors = await this.getInterceptorStrings(testId);
|
|
2998
|
-
const
|
|
2999
|
-
const itBody = `it('${escapeSingleQuotes(record.name)}', () => {
|
|
2826
|
+
const itBlock = `it('${escapeSingleQuotes(record.name)}', () => {
|
|
3000
2827
|
${commands.map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
3001
2828
|
});`;
|
|
3002
|
-
const itBlock = ticketComment ? `${ticketComment}
|
|
3003
|
-
${itBody}` : itBody;
|
|
3004
2829
|
const interceptorsBlock = interceptors.length ? " // Auto-generated Cypress interceptors\n" + interceptors.map((i) => normalizeBlock(i, " ")).join("\n") + "\n" : "";
|
|
3005
2830
|
return { ...record, commands, interceptors, cypressCommands: commands, itBlock, interceptorsBlock };
|
|
3006
2831
|
}
|
|
3007
|
-
/**
|
|
3008
|
-
* Builds the traceability comment for a test record (spec 014), reading the
|
|
3009
|
-
* configured issue-tracker provider/params so the link — when resolvable — is
|
|
3010
|
-
* embedded. Returns `null` when the record has no ticket id.
|
|
3011
|
-
*/
|
|
3012
|
-
async ticketCommentFor(record) {
|
|
3013
|
-
if (!record.ticketId) return null;
|
|
3014
|
-
const config = await this.getGeneralConfig();
|
|
3015
|
-
const providerId = config?.["issueTrackerProviderId"] ?? DEFAULT_ISSUE_TRACKER_PROVIDER_ID;
|
|
3016
|
-
const params = config?.["issueTrackerParams"] ?? {};
|
|
3017
|
-
const url = resolveTicketUrl(providerId, params, record.ticketId);
|
|
3018
|
-
return buildTicketComment(record.ticketId, url);
|
|
3019
|
-
}
|
|
3020
2832
|
async deleteTest(id) {
|
|
3021
2833
|
const db = await this.getDB();
|
|
3022
2834
|
await db.delete("tests", id);
|
|
@@ -3324,39 +3136,34 @@ var HttpMonitor = class {
|
|
|
3324
3136
|
if (!INTERCEPTED_METHODS.includes(method)) return;
|
|
3325
3137
|
const url = resolveUrl(input);
|
|
3326
3138
|
const alias = generateAlias(method, url);
|
|
3327
|
-
if (this.isFixtureModeEnabled() && method === "GET") {
|
|
3328
|
-
const pretty = prettyJsonOrNull(await responseClone.text());
|
|
3329
|
-
const fixtureFile = `${alias}.json`;
|
|
3330
|
-
if (pretty !== null) this.recording.registerFixture(fixtureFile, pretty);
|
|
3331
|
-
this.recording.registerInterceptor(method, url, alias, pretty !== null ? fixtureFile : void 0);
|
|
3332
|
-
this.recording.addCommand(`cy.wait('@${alias}').then((interception) => { })`);
|
|
3333
|
-
return;
|
|
3334
|
-
}
|
|
3335
3139
|
this.recording.registerInterceptor(method, url, alias);
|
|
3336
3140
|
const extendedHttp = this.isExtendedHttpEnabled();
|
|
3141
|
+
const fixtureMode = this.isFixtureModeEnabled();
|
|
3337
3142
|
const requestBody = extendedHttp ? parseRequestBody(init) : null;
|
|
3143
|
+
let responseText = null;
|
|
3338
3144
|
let responseBody = null;
|
|
3339
|
-
if (extendedHttp) {
|
|
3145
|
+
if (extendedHttp || fixtureMode && method === "GET") {
|
|
3340
3146
|
try {
|
|
3341
|
-
|
|
3147
|
+
responseText = await responseClone.text();
|
|
3148
|
+
if (extendedHttp) responseBody = parseJsonObject(responseText);
|
|
3342
3149
|
} catch {
|
|
3343
3150
|
}
|
|
3344
3151
|
}
|
|
3152
|
+
if (fixtureMode && method === "GET" && responseText !== null) {
|
|
3153
|
+
const pretty = prettyJsonOrNull(responseText);
|
|
3154
|
+
if (pretty !== null) this.recording.registerFixture(`${alias}.json`, pretty);
|
|
3155
|
+
}
|
|
3345
3156
|
const cmd = buildCyWaitCommand(method, alias, extendedHttp, requestBody, responseBody);
|
|
3346
3157
|
this.recording.addCommand(cmd);
|
|
3347
3158
|
}
|
|
3348
3159
|
handleXhrInterception(method, url, requestBody, responseText) {
|
|
3349
3160
|
if (!INTERCEPTED_METHODS.includes(method)) return;
|
|
3350
3161
|
const alias = generateAlias(method, url);
|
|
3162
|
+
this.recording.registerInterceptor(method, url, alias);
|
|
3351
3163
|
if (this.isFixtureModeEnabled() && method === "GET") {
|
|
3352
3164
|
const pretty = prettyJsonOrNull(responseText);
|
|
3353
|
-
|
|
3354
|
-
if (pretty !== null) this.recording.registerFixture(fixtureFile, pretty);
|
|
3355
|
-
this.recording.registerInterceptor(method, url, alias, pretty !== null ? fixtureFile : void 0);
|
|
3356
|
-
this.recording.addCommand(`cy.wait('@${alias}').then((interception) => { })`);
|
|
3357
|
-
return;
|
|
3165
|
+
if (pretty !== null) this.recording.registerFixture(`${alias}.json`, pretty);
|
|
3358
3166
|
}
|
|
3359
|
-
this.recording.registerInterceptor(method, url, alias);
|
|
3360
3167
|
const extendedHttp = this.isExtendedHttpEnabled();
|
|
3361
3168
|
const responseBody = extendedHttp ? parseJsonObject(responseText) : null;
|
|
3362
3169
|
const cmd = buildCyWaitCommand(method, alias, extendedHttp, requestBody, responseBody);
|
|
@@ -3681,177 +3488,6 @@ function boxTopLeftFor(toggleCentre, dir) {
|
|
|
3681
3488
|
return { x: toggleCentre.x - off.x, y: toggleCentre.y - off.y };
|
|
3682
3489
|
}
|
|
3683
3490
|
|
|
3684
|
-
// src/utils/cypress-completions.ts
|
|
3685
|
-
var CY_METHODS = [
|
|
3686
|
-
"visit",
|
|
3687
|
-
"get",
|
|
3688
|
-
"contains",
|
|
3689
|
-
"intercept",
|
|
3690
|
-
"wait",
|
|
3691
|
-
"request",
|
|
3692
|
-
"url",
|
|
3693
|
-
"location",
|
|
3694
|
-
"viewport",
|
|
3695
|
-
"fixture",
|
|
3696
|
-
"wrap",
|
|
3697
|
-
"reload",
|
|
3698
|
-
"go",
|
|
3699
|
-
"window",
|
|
3700
|
-
"document",
|
|
3701
|
-
"session",
|
|
3702
|
-
"clearCookies",
|
|
3703
|
-
"clearLocalStorage",
|
|
3704
|
-
"screenshot",
|
|
3705
|
-
"log"
|
|
3706
|
-
];
|
|
3707
|
-
var CHAIN_METHODS = [
|
|
3708
|
-
"click",
|
|
3709
|
-
"dblclick",
|
|
3710
|
-
"rightclick",
|
|
3711
|
-
"type",
|
|
3712
|
-
"clear",
|
|
3713
|
-
"select",
|
|
3714
|
-
"check",
|
|
3715
|
-
"uncheck",
|
|
3716
|
-
"should",
|
|
3717
|
-
"and",
|
|
3718
|
-
"find",
|
|
3719
|
-
"first",
|
|
3720
|
-
"last",
|
|
3721
|
-
"eq",
|
|
3722
|
-
"then",
|
|
3723
|
-
"its",
|
|
3724
|
-
"invoke",
|
|
3725
|
-
"as",
|
|
3726
|
-
"trigger",
|
|
3727
|
-
"focus",
|
|
3728
|
-
"blur",
|
|
3729
|
-
"scrollIntoView",
|
|
3730
|
-
"within",
|
|
3731
|
-
"parent",
|
|
3732
|
-
"children",
|
|
3733
|
-
"siblings",
|
|
3734
|
-
"contains",
|
|
3735
|
-
"each",
|
|
3736
|
-
"filter",
|
|
3737
|
-
"wait"
|
|
3738
|
-
];
|
|
3739
|
-
var TOP_LEVEL = [
|
|
3740
|
-
"cy",
|
|
3741
|
-
"describe",
|
|
3742
|
-
"it",
|
|
3743
|
-
"context",
|
|
3744
|
-
"beforeEach",
|
|
3745
|
-
"afterEach",
|
|
3746
|
-
"before",
|
|
3747
|
-
"after",
|
|
3748
|
-
"Cypress"
|
|
3749
|
-
];
|
|
3750
|
-
var CYPRESS_COMPLETIONS = [
|
|
3751
|
-
...TOP_LEVEL,
|
|
3752
|
-
...CY_METHODS.map((m) => `cy.${m}`),
|
|
3753
|
-
...CHAIN_METHODS
|
|
3754
|
-
];
|
|
3755
|
-
function filterCompletions(list, prefix) {
|
|
3756
|
-
const p = prefix.toLowerCase();
|
|
3757
|
-
if (!p) return [...list];
|
|
3758
|
-
return list.filter((label) => label.toLowerCase().includes(p));
|
|
3759
|
-
}
|
|
3760
|
-
function filterCypressCompletions(prefix) {
|
|
3761
|
-
return filterCompletions(CYPRESS_COMPLETIONS, prefix);
|
|
3762
|
-
}
|
|
3763
|
-
|
|
3764
|
-
// src/utils/code-editor.ts
|
|
3765
|
-
function toOptions(labels, type) {
|
|
3766
|
-
return labels.map((label) => ({ label, type }));
|
|
3767
|
-
}
|
|
3768
|
-
function cypressCompletionSource(context) {
|
|
3769
|
-
const cyMatch = context.matchBefore(/cy\.\w*$/);
|
|
3770
|
-
if (cyMatch) {
|
|
3771
|
-
return { from: cyMatch.from + 3, options: toOptions(filterCompletions(CY_METHODS, cyMatch.text.slice(3)), "method") };
|
|
3772
|
-
}
|
|
3773
|
-
const chainMatch = context.matchBefore(/\.\w*$/);
|
|
3774
|
-
if (chainMatch) {
|
|
3775
|
-
return { from: chainMatch.from + 1, options: toOptions(filterCompletions(CHAIN_METHODS, chainMatch.text.slice(1)), "method") };
|
|
3776
|
-
}
|
|
3777
|
-
const word = context.matchBefore(/\w*/);
|
|
3778
|
-
if (!word || word.from === word.to && !context.explicit) return null;
|
|
3779
|
-
return { from: word.from, options: toOptions(filterCompletions(TOP_LEVEL, word.text), "keyword") };
|
|
3780
|
-
}
|
|
3781
|
-
async function createCodeEditor(opts) {
|
|
3782
|
-
const [view, state, language, langJs, autocomplete, commands, highlight] = await Promise.all([
|
|
3783
|
-
import("@codemirror/view"),
|
|
3784
|
-
import("@codemirror/state"),
|
|
3785
|
-
import("@codemirror/language"),
|
|
3786
|
-
import("@codemirror/lang-javascript"),
|
|
3787
|
-
import("@codemirror/autocomplete"),
|
|
3788
|
-
import("@codemirror/commands"),
|
|
3789
|
-
import("@lezer/highlight")
|
|
3790
|
-
]);
|
|
3791
|
-
const { EditorView, keymap, lineNumbers, highlightActiveLine, drawSelection } = view;
|
|
3792
|
-
const { EditorState } = state;
|
|
3793
|
-
const { syntaxHighlighting, HighlightStyle, indentOnInput, bracketMatching } = language;
|
|
3794
|
-
const { javascript } = langJs;
|
|
3795
|
-
const { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } = autocomplete;
|
|
3796
|
-
const { history: history2, defaultKeymap, historyKeymap, indentWithTab } = commands;
|
|
3797
|
-
const { tags } = highlight;
|
|
3798
|
-
const darkHighlight = HighlightStyle.define([
|
|
3799
|
-
{ tag: tags.keyword, color: "#ff7b72" },
|
|
3800
|
-
{ tag: tags.string, color: "#a5d6ff" },
|
|
3801
|
-
{ tag: [tags.function(tags.variableName), tags.function(tags.propertyName)], color: "#d2a8ff" },
|
|
3802
|
-
{ tag: tags.number, color: "#79c0ff" },
|
|
3803
|
-
{ tag: [tags.bool, tags.null], color: "#79c0ff" },
|
|
3804
|
-
{ tag: tags.comment, color: "#8b949e", fontStyle: "italic" },
|
|
3805
|
-
{ tag: [tags.propertyName, tags.attributeName], color: "#7ee787" },
|
|
3806
|
-
{ tag: [tags.typeName, tags.className], color: "#ffa657" },
|
|
3807
|
-
{ tag: tags.operator, color: "#ff7b72" },
|
|
3808
|
-
{ tag: [tags.brace, tags.bracket, tags.punctuation], color: "#c9d1d9" }
|
|
3809
|
-
]);
|
|
3810
|
-
const theme = EditorView.theme(
|
|
3811
|
-
{
|
|
3812
|
-
"&": { color: "#c9d1d9", backgroundColor: "#0d1117", height: "100%", fontSize: "13px" },
|
|
3813
|
-
".cm-scroller": { fontFamily: "'Cascadia Code','Fira Code',Consolas,monospace", overflow: "auto" },
|
|
3814
|
-
".cm-gutters": { backgroundColor: "#0d1117", color: "#484f58", border: "none" },
|
|
3815
|
-
".cm-activeLine": { backgroundColor: "rgba(110,118,129,0.10)" },
|
|
3816
|
-
".cm-activeLineGutter": { backgroundColor: "transparent" },
|
|
3817
|
-
"&.cm-focused": { outline: "none" },
|
|
3818
|
-
".cm-tooltip": { background: "#161b22", border: "1px solid #30363d", color: "#c9d1d9", borderRadius: "6px" },
|
|
3819
|
-
".cm-tooltip-autocomplete ul li[aria-selected]": { background: "#1f6feb", color: "#fff" }
|
|
3820
|
-
},
|
|
3821
|
-
{ dark: true }
|
|
3822
|
-
);
|
|
3823
|
-
const editorView = new EditorView({
|
|
3824
|
-
parent: opts.parent,
|
|
3825
|
-
...opts.root ? { root: opts.root } : {},
|
|
3826
|
-
state: EditorState.create({
|
|
3827
|
-
doc: opts.doc,
|
|
3828
|
-
extensions: [
|
|
3829
|
-
lineNumbers(),
|
|
3830
|
-
highlightActiveLine(),
|
|
3831
|
-
drawSelection(),
|
|
3832
|
-
history2(),
|
|
3833
|
-
indentOnInput(),
|
|
3834
|
-
bracketMatching(),
|
|
3835
|
-
closeBrackets(),
|
|
3836
|
-
javascript({ typescript: true }),
|
|
3837
|
-
syntaxHighlighting(darkHighlight),
|
|
3838
|
-
autocompletion({ override: [cypressCompletionSource] }),
|
|
3839
|
-
keymap.of([...closeBracketsKeymap, ...defaultKeymap, ...historyKeymap, ...completionKeymap, indentWithTab]),
|
|
3840
|
-
theme,
|
|
3841
|
-
EditorView.updateListener.of((update) => {
|
|
3842
|
-
if (update.docChanged && opts.onChange) opts.onChange(update.state.doc.toString());
|
|
3843
|
-
})
|
|
3844
|
-
]
|
|
3845
|
-
})
|
|
3846
|
-
});
|
|
3847
|
-
return {
|
|
3848
|
-
getValue: () => editorView.state.doc.toString(),
|
|
3849
|
-
setValue: (value) => editorView.dispatch({ changes: { from: 0, to: editorView.state.doc.length, insert: value } }),
|
|
3850
|
-
focus: () => editorView.focus(),
|
|
3851
|
-
destroy: () => editorView.destroy()
|
|
3852
|
-
};
|
|
3853
|
-
}
|
|
3854
|
-
|
|
3855
3491
|
// src/index.ts
|
|
3856
3492
|
init_selector_picker();
|
|
3857
3493
|
|
|
@@ -4057,6 +3693,33 @@ if (!customElements.get("test-previsualizer")) {
|
|
|
4057
3693
|
customElements.define("test-previsualizer", TestPrevisualizerElement);
|
|
4058
3694
|
}
|
|
4059
3695
|
|
|
3696
|
+
// src/models/issue-tracker.model.ts
|
|
3697
|
+
var ISSUE_TRACKER_PRESETS = {
|
|
3698
|
+
jira: { id: "jira", label: "Jira", urlPattern: "{baseUrl}/browse/{id}", idPattern: /^[A-Z][A-Z0-9]+-\d+$/ },
|
|
3699
|
+
github: { id: "github", label: "GitHub Issues", urlPattern: "{baseUrl}/issues/{id}", idPattern: /^\d+$/ },
|
|
3700
|
+
gitlab: { id: "gitlab", label: "GitLab Issues", urlPattern: "{baseUrl}/-/issues/{id}", idPattern: /^\d+$/ },
|
|
3701
|
+
azure: { id: "azure", label: "Azure DevOps", urlPattern: "{baseUrl}/_workitems/edit/{id}", idPattern: /^\d+$/ },
|
|
3702
|
+
bitbucket: { id: "bitbucket", label: "Bitbucket Issues", urlPattern: "{baseUrl}/issues/{id}", idPattern: /^\d+$/ },
|
|
3703
|
+
custom: { id: "custom", label: "Custom", urlPattern: "{baseUrl}/{id}", idPattern: /.+/ }
|
|
3704
|
+
};
|
|
3705
|
+
var DEFAULT_ISSUE_TRACKER_CONFIG = {
|
|
3706
|
+
enabled: false,
|
|
3707
|
+
provider: "jira",
|
|
3708
|
+
baseUrl: ""
|
|
3709
|
+
};
|
|
3710
|
+
|
|
3711
|
+
// src/utils/ticket.utils.ts
|
|
3712
|
+
function buildTicketUrl(ticketId, config) {
|
|
3713
|
+
if (!config.enabled || !ticketId.trim() || !config.baseUrl.trim()) return null;
|
|
3714
|
+
const preset = ISSUE_TRACKER_PRESETS[config.provider];
|
|
3715
|
+
const base = config.baseUrl.replace(/\/+$/, "");
|
|
3716
|
+
return preset.urlPattern.replace("{baseUrl}", base).replace("{id}", encodeURIComponent(ticketId.trim()));
|
|
3717
|
+
}
|
|
3718
|
+
function isValidTicketId(ticketId, provider) {
|
|
3719
|
+
if (!ticketId.trim()) return false;
|
|
3720
|
+
return ISSUE_TRACKER_PRESETS[provider].idPattern.test(ticketId.trim());
|
|
3721
|
+
}
|
|
3722
|
+
|
|
4060
3723
|
// src/components/save-test/save-test.styles.ts
|
|
4061
3724
|
var SAVE_TEST_STYLES = `
|
|
4062
3725
|
:host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }
|
|
@@ -4132,11 +3795,15 @@ function renderSaveTestAsk(t) {
|
|
|
4132
3795
|
</div>
|
|
4133
3796
|
</div>`;
|
|
4134
3797
|
}
|
|
4135
|
-
function renderSaveTestDesc(description, notes, tags,
|
|
3798
|
+
function renderSaveTestDesc(description, notes, tags, ticketId, issueTrackerEnabled, ticketWarn, t) {
|
|
4136
3799
|
const chipsHtml = tags.map(
|
|
4137
3800
|
(tag) => `<span class="chip">${escHtml(tag)}<button class="chip-del" data-tag="${escAttr(tag)}" title="${t("SAVE_TEST.REMOVE_TAG_TITLE")}">\u2715</button></span>`
|
|
4138
3801
|
).join("");
|
|
4139
|
-
const
|
|
3802
|
+
const ticketHtml = issueTrackerEnabled ? `
|
|
3803
|
+
<span class="tag-label">${t("SAVE_TEST.TICKET_LABEL")}</span>
|
|
3804
|
+
<input id="ticket-input" type="text" placeholder="${escAttr(t("SAVE_TEST.TICKET_PLACEHOLDER"))}"
|
|
3805
|
+
value="${escAttr(ticketId)}" autocomplete="off" />
|
|
3806
|
+
${ticketWarn ? `<span class="ticket-warn">\u26A0 ${t("SAVE_TEST.TICKET_WARN")}</span>` : ""}` : "";
|
|
4140
3807
|
return `
|
|
4141
3808
|
<div class="container">
|
|
4142
3809
|
<p>${t("SAVE_TEST.DESC_LABEL")} (<code>it()</code>):</p>
|
|
@@ -4144,16 +3811,13 @@ function renderSaveTestDesc(description, notes, tags, ticket, t) {
|
|
|
4144
3811
|
value="${escAttr(description)}" autocomplete="off" />
|
|
4145
3812
|
<span class="tag-label">${t("SAVE_TEST.NOTES_LABEL")}</span>
|
|
4146
3813
|
<textarea id="notes-input" rows="3" placeholder="${escAttr(t("SAVE_TEST.NOTES_PLACEHOLDER"))}">${escHtml(notes)}</textarea>
|
|
4147
|
-
<span class="tag-label">${t("SAVE_TEST.TICKET_LABEL")}</span>
|
|
4148
|
-
<input id="ticket-input" type="text" placeholder="${escAttr(t(ticket.placeholderKey))}"
|
|
4149
|
-
value="${escAttr(ticket.id)}" autocomplete="off" />
|
|
4150
|
-
${ticketWarning}
|
|
4151
3814
|
<span class="tag-label">${t("SAVE_TEST.TAGS_LABEL")}</span>
|
|
4152
3815
|
<div class="tag-input-row">
|
|
4153
3816
|
<input id="tag-input" type="text" placeholder="${t("SAVE_TEST.TAGS_PLACEHOLDER")}" autocomplete="off" />
|
|
4154
3817
|
<button class="btn-tag-add" id="btn-add-tag">${t("SAVE_TEST.ADD_TAG")}</button>
|
|
4155
3818
|
</div>
|
|
4156
3819
|
<div class="chips" id="chips-container">${chipsHtml || `<span style="color:#484f58;font-size:11px">${t("SAVE_TEST.NO_TAGS")}</span>`}</div>
|
|
3820
|
+
${ticketHtml}
|
|
4157
3821
|
<div class="btn-row">
|
|
4158
3822
|
<button class="btn-primary" id="btn-confirm">${t("SAVE_TEST.SAVE_BTN")}</button>
|
|
4159
3823
|
<button class="btn-success" id="btn-export">${t("SAVE_TEST.SAVE_AND_EDIT")}</button>
|
|
@@ -4170,8 +3834,7 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
4170
3834
|
notes = "";
|
|
4171
3835
|
tags = [];
|
|
4172
3836
|
ticketId = "";
|
|
4173
|
-
|
|
4174
|
-
issueTrackerProviderId = DEFAULT_ISSUE_TRACKER_PROVIDER_ID;
|
|
3837
|
+
issueTrackerConfig = DEFAULT_ISSUE_TRACKER_CONFIG;
|
|
4175
3838
|
translation = translationService;
|
|
4176
3839
|
constructor() {
|
|
4177
3840
|
super();
|
|
@@ -4188,13 +3851,13 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
4188
3851
|
this.render();
|
|
4189
3852
|
}
|
|
4190
3853
|
confirmSave() {
|
|
4191
|
-
this.dispatch("savetest", { description: this.description.trim(), notes: this.notes, tags: [...this.tags], ticketId: this.ticketId.trim()
|
|
3854
|
+
this.dispatch("savetest", { description: this.description.trim(), notes: this.notes, tags: [...this.tags], ticketId: this.ticketId.trim() });
|
|
4192
3855
|
}
|
|
4193
3856
|
confirmSaveAndExport() {
|
|
4194
|
-
this.dispatch("saveandexport", { description: this.description.trim(), notes: this.notes, tags: [...this.tags], ticketId: this.ticketId.trim()
|
|
3857
|
+
this.dispatch("saveandexport", { description: this.description.trim(), notes: this.notes, tags: [...this.tags], ticketId: this.ticketId.trim() });
|
|
4195
3858
|
}
|
|
4196
3859
|
cancel() {
|
|
4197
|
-
this.dispatch("savetest", { description: null, notes: "", tags: [], ticketId:
|
|
3860
|
+
this.dispatch("savetest", { description: null, notes: "", tags: [], ticketId: "" });
|
|
4198
3861
|
}
|
|
4199
3862
|
restartComponent() {
|
|
4200
3863
|
this._step = "ask";
|
|
@@ -4218,19 +3881,9 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
4218
3881
|
t(key) {
|
|
4219
3882
|
return this.translation.translate(key);
|
|
4220
3883
|
}
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
const trimmed = this.ticketId.trim();
|
|
4225
|
-
let invalid = false;
|
|
4226
|
-
if (trimmed) {
|
|
4227
|
-
try {
|
|
4228
|
-
invalid = !new RegExp(provider.idPattern).test(trimmed);
|
|
4229
|
-
} catch {
|
|
4230
|
-
invalid = false;
|
|
4231
|
-
}
|
|
4232
|
-
}
|
|
4233
|
-
return { id: this.ticketId, placeholderKey: provider.idPlaceholderKey, invalid };
|
|
3884
|
+
get ticketIdWarning() {
|
|
3885
|
+
if (!this.ticketId.trim() || !this.issueTrackerConfig.enabled) return false;
|
|
3886
|
+
return !isValidTicketId(this.ticketId, this.issueTrackerConfig.provider);
|
|
4234
3887
|
}
|
|
4235
3888
|
dispatch(type, detail) {
|
|
4236
3889
|
this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));
|
|
@@ -4241,21 +3894,18 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
4241
3894
|
this.shadow.getElementById("btn-yes")?.addEventListener("click", () => this.askSave());
|
|
4242
3895
|
this.shadow.getElementById("btn-no")?.addEventListener("click", () => this.cancel());
|
|
4243
3896
|
} else {
|
|
4244
|
-
this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestDesc(this.description, this.notes, this.tags, this.
|
|
3897
|
+
this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestDesc(this.description, this.notes, this.tags, this.ticketId, this.issueTrackerConfig.enabled, this.ticketIdWarning, this.t.bind(this))}`;
|
|
4245
3898
|
const descInput = this.shadow.getElementById("desc-input");
|
|
4246
3899
|
const notesInput = this.shadow.getElementById("notes-input");
|
|
4247
|
-
const ticketInput = this.shadow.getElementById("ticket-input");
|
|
4248
3900
|
const tagInput = this.shadow.getElementById("tag-input");
|
|
3901
|
+
const ticketInput = this.shadow.getElementById("ticket-input");
|
|
4249
3902
|
descInput.addEventListener("input", () => {
|
|
4250
3903
|
this.description = descInput.value;
|
|
4251
3904
|
});
|
|
4252
3905
|
notesInput.addEventListener("input", () => {
|
|
4253
3906
|
this.notes = notesInput.value;
|
|
4254
3907
|
});
|
|
4255
|
-
ticketInput
|
|
4256
|
-
this.ticketId = ticketInput.value;
|
|
4257
|
-
});
|
|
4258
|
-
ticketInput.addEventListener("change", () => {
|
|
3908
|
+
ticketInput?.addEventListener("input", () => {
|
|
4259
3909
|
this.ticketId = ticketInput.value;
|
|
4260
3910
|
this.render();
|
|
4261
3911
|
});
|
|
@@ -4350,6 +4000,18 @@ var TEST_EDITOR_STYLES = `
|
|
|
4350
4000
|
padding: 1px 7px; border-radius: 20px; font-size: 10px;
|
|
4351
4001
|
background: rgba(47,129,247,0.1); color: #8b949e; border: 1px solid rgba(47,129,247,0.2);
|
|
4352
4002
|
}
|
|
4003
|
+
.ticket-badge, .ticket-link {
|
|
4004
|
+
padding: 1px 7px; border-radius: 20px; font-size: 10px; font-weight: 500;
|
|
4005
|
+
background: rgba(210,153,34,0.12); color: #d29922; border: 1px solid rgba(210,153,34,0.3);
|
|
4006
|
+
white-space: nowrap; flex-shrink: 0;
|
|
4007
|
+
}
|
|
4008
|
+
.ticket-link {
|
|
4009
|
+
text-decoration: none; cursor: pointer;
|
|
4010
|
+
transition: background 0.12s, border-color 0.12s;
|
|
4011
|
+
}
|
|
4012
|
+
.ticket-link::before { content: '\u{1F3AB} '; font-size: 9px; }
|
|
4013
|
+
.ticket-link:hover { background: rgba(210,153,34,0.22); border-color: rgba(210,153,34,0.55); color: #e3b341; }
|
|
4014
|
+
.ticket-badge::before { content: '\u{1F3AB} '; font-size: 9px; }
|
|
4353
4015
|
.btn-icon {
|
|
4354
4016
|
padding: 3px 8px; border: none; border-radius: 6px; cursor: pointer;
|
|
4355
4017
|
font-size: 11px; background: #21262d; color: #8b949e;
|
|
@@ -4381,6 +4043,13 @@ var TEST_EDITOR_STYLES = `
|
|
|
4381
4043
|
.code-preview::-webkit-scrollbar { height: 4px; }
|
|
4382
4044
|
.code-preview::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }
|
|
4383
4045
|
.code-preview-icp { margin-top: 8px; }
|
|
4046
|
+
.ticket-group { margin-bottom: 8px; }
|
|
4047
|
+
.ticket-group-header {
|
|
4048
|
+
padding: 4px 10px; margin-bottom: 4px;
|
|
4049
|
+
font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.7px;
|
|
4050
|
+
color: #d29922; border-left: 3px solid rgba(210,153,34,0.5);
|
|
4051
|
+
background: rgba(210,153,34,0.06); border-radius: 0 4px 4px 0;
|
|
4052
|
+
}
|
|
4384
4053
|
.sh-kw { color: #ff7b72; }
|
|
4385
4054
|
.sh-bi { color: #d2a8ff; }
|
|
4386
4055
|
.sh-str { color: #a5d6ff; }
|
|
@@ -4487,8 +4156,48 @@ function highlightLine(line) {
|
|
|
4487
4156
|
}
|
|
4488
4157
|
|
|
4489
4158
|
// src/components/test-editor/test-editor.template.ts
|
|
4159
|
+
function renderTestRow(test, i, state, t) {
|
|
4160
|
+
const { selectMode, selectedIds, expandedIndex, interceptorsByTest, locale, issueTrackerConfig } = state;
|
|
4161
|
+
const expanded = expandedIndex === i;
|
|
4162
|
+
const date = new Date(test.createdAt).toLocaleString(locale, { day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit" });
|
|
4163
|
+
const icps = interceptorsByTest[test.id] ?? test.interceptors ?? [];
|
|
4164
|
+
const tagsHtml = (test.tags ?? []).length ? `<span class="test-tags">${(test.tags ?? []).map((tag) => `<span class="test-tag">${escHtml(tag)}</span>`).join("")}</span>` : "";
|
|
4165
|
+
const checkbox = selectMode ? `<input type="checkbox" ${selectedIds.has(test.id) ? "checked" : ""} data-select="${test.id}" />` : "";
|
|
4166
|
+
const hasIcps = (test.interceptors ?? []).length > 0;
|
|
4167
|
+
const itBlockCode = `it('${escapeSingleQuotes(test.name)}', () => {
|
|
4168
|
+
${(test.commands ?? []).map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
4169
|
+
});`;
|
|
4170
|
+
const icpBlockCode = icps.length ? `beforeEach(() => {
|
|
4171
|
+
// Auto-generated Cypress interceptors
|
|
4172
|
+
${icps.map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
4173
|
+
});` : "";
|
|
4174
|
+
const notesHtml = expanded && test.notes ? `<p class="test-notes">${escHtml(test.notes)}</p>` : "";
|
|
4175
|
+
const ticketId = test.ticketId;
|
|
4176
|
+
const ticketUrl = ticketId ? buildTicketUrl(ticketId, issueTrackerConfig) : null;
|
|
4177
|
+
const ticketHtml = ticketId ? ticketUrl ? `<a class="ticket-link" href="${escAttr(ticketUrl)}" target="_blank" rel="noopener noreferrer" title="${t("TEST_EDITOR.TICKET_LINK_TITLE")}">${escHtml(ticketId)}</a>` : `<span class="ticket-badge">${escHtml(ticketId)}</span>` : "";
|
|
4178
|
+
const body = expanded ? `
|
|
4179
|
+
<div class="row-body">
|
|
4180
|
+
${notesHtml}
|
|
4181
|
+
<pre class="code-preview">${syntaxHighlight(itBlockCode)}</pre>
|
|
4182
|
+
${icpBlockCode ? `<pre class="code-preview code-preview-icp">${syntaxHighlight(icpBlockCode)}</pre>` : ""}
|
|
4183
|
+
</div>` : "";
|
|
4184
|
+
return `
|
|
4185
|
+
<div class="row${selectedIds.has(test.id) ? " selected-row" : ""}">
|
|
4186
|
+
<div class="row-header" data-action="expand" data-idx="${i}">
|
|
4187
|
+
${checkbox}
|
|
4188
|
+
<span class="test-name">${escHtml(test.name)}</span>
|
|
4189
|
+
${tagsHtml}
|
|
4190
|
+
${ticketHtml}
|
|
4191
|
+
<span class="test-date">${date}</span>
|
|
4192
|
+
<button class="btn-icon" data-action="copy-cmds" data-idx="${i}" title="${t("TEST_EDITOR.COPY_CMDS_BTN")}">${t("TEST_EDITOR.COPY_CMDS_BTN")}</button>
|
|
4193
|
+
${hasIcps ? `<button class="btn-icon" data-action="copy-icps" data-idx="${i}" title="${t("TEST_EDITOR.COPY_ICPS_BTN")}">${t("TEST_EDITOR.COPY_ICPS_BTN")}</button>` : ""}
|
|
4194
|
+
<button class="btn-icon btn-del" data-action="delete" data-id="${test.id}" title="${t("TEST_EDITOR.DELETE_TITLE")}">\u{1F5D1}</button>
|
|
4195
|
+
</div>
|
|
4196
|
+
${body}
|
|
4197
|
+
</div>`;
|
|
4198
|
+
}
|
|
4490
4199
|
function renderTestEditor(state, t) {
|
|
4491
|
-
const { tags, visible, selectedVisible, activeTag, selectMode,
|
|
4200
|
+
const { tags, visible, selectedVisible, activeTag, selectMode, describeName, groupByTicket } = state;
|
|
4492
4201
|
const tagFilterHtml = tags.length ? `<div class="tag-filter">
|
|
4493
4202
|
${tags.map((tag) => `<button class="tag-chip${activeTag === tag ? " active" : ""}" data-filter-tag="${escAttr(tag)}">${escHtml(tag)}</button>`).join("")}
|
|
4494
4203
|
</div>` : `<div class="tag-filter" style="color:#484f58;font-size:11px">${t("TEST_EDITOR.NO_TAGS")}</div>`;
|
|
@@ -4497,80 +4206,43 @@ function renderTestEditor(state, t) {
|
|
|
4497
4206
|
<input id="describe-name" type="text" placeholder="${t("TEST_EDITOR.DESCRIBE_PLACEHOLDER")}" value="${escAttr(describeName)}" />
|
|
4498
4207
|
<button class="btn-gen-describe" id="btn-gen-describe">${t("TEST_EDITOR.COPY_DESCRIBE")}</button>
|
|
4499
4208
|
</div>` : "";
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
const date = new Date(test.createdAt).toLocaleString(locale, { day: "2-digit", month: "2-digit", hour: "2-digit", minute: "2-digit" });
|
|
4503
|
-
const icps = interceptorsByTest[test.id] ?? test.interceptors ?? [];
|
|
4504
|
-
const tagsHtml = (test.tags ?? []).length ? `<span class="test-tags">${(test.tags ?? []).map((tag) => `<span class="test-tag">${escHtml(tag)}</span>`).join("")}</span>` : "";
|
|
4505
|
-
const ticketId = (test.ticketId ?? "").trim();
|
|
4506
|
-
const ticketUrl = ticketUrlByTest[test.id] ?? null;
|
|
4507
|
-
const ticketHtml = !ticketId ? "" : ticketUrl ? `<a class="test-ticket" data-ticket-link href="${escAttr(ticketUrl)}" target="_blank" rel="noopener noreferrer" style="color:#58a6ff;font-size:11px;text-decoration:none">\u{1F3AB} ${escHtml(ticketId)}</a>` : `<span class="test-ticket" style="color:#8b949e;font-size:11px">\u{1F3AB} ${escHtml(ticketId)}</span>`;
|
|
4508
|
-
const checkbox = selectMode ? `<input type="checkbox" ${selectedIds.has(test.id) ? "checked" : ""} data-select="${test.id}" />` : "";
|
|
4509
|
-
const hasIcps = (test.interceptors ?? []).length > 0;
|
|
4510
|
-
const ticketComment = ticketId ? `${buildTicketComment(ticketId, ticketUrl)}
|
|
4511
|
-
` : "";
|
|
4512
|
-
const itBlockCode = `${ticketComment}it('${escapeSingleQuotes(test.name)}', () => {
|
|
4513
|
-
${(test.commands ?? []).map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
4514
|
-
});`;
|
|
4515
|
-
const icpBlockCode = icps.length ? `beforeEach(() => {
|
|
4516
|
-
// Auto-generated Cypress interceptors
|
|
4517
|
-
${icps.map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
4518
|
-
});` : "";
|
|
4519
|
-
const notesHtml = expanded && test.notes ? `<p class="test-notes">${escHtml(test.notes)}</p>` : "";
|
|
4520
|
-
const body = expanded ? `
|
|
4521
|
-
<div class="row-body">
|
|
4522
|
-
${notesHtml}
|
|
4523
|
-
<pre class="code-preview">${syntaxHighlight(itBlockCode)}</pre>
|
|
4524
|
-
${icpBlockCode ? `<pre class="code-preview code-preview-icp">${syntaxHighlight(icpBlockCode)}</pre>` : ""}
|
|
4525
|
-
</div>` : "";
|
|
4526
|
-
return `
|
|
4527
|
-
<div class="row${selectedIds.has(test.id) ? " selected-row" : ""}">
|
|
4528
|
-
<div class="row-header" data-action="expand" data-idx="${i}">
|
|
4529
|
-
${checkbox}
|
|
4530
|
-
<span class="test-name">${escHtml(test.name)}</span>
|
|
4531
|
-
${tagsHtml}
|
|
4532
|
-
${ticketHtml}
|
|
4533
|
-
<span class="test-date">${date}</span>
|
|
4534
|
-
<button class="btn-icon" data-action="copy-cmds" data-idx="${i}" title="${t("TEST_EDITOR.COPY_CMDS_BTN")}">${t("TEST_EDITOR.COPY_CMDS_BTN")}</button>
|
|
4535
|
-
${hasIcps ? `<button class="btn-icon" data-action="copy-icps" data-idx="${i}" title="${t("TEST_EDITOR.COPY_ICPS_BTN")}">${t("TEST_EDITOR.COPY_ICPS_BTN")}</button>` : ""}
|
|
4536
|
-
<button class="btn-icon btn-del" data-action="delete" data-id="${test.id}" title="${t("TEST_EDITOR.DELETE_TITLE")}">\u{1F5D1}</button>
|
|
4537
|
-
</div>
|
|
4538
|
-
${body}
|
|
4539
|
-
</div>`;
|
|
4540
|
-
};
|
|
4541
|
-
const indexed = visible.map((test, i) => ({ test, i }));
|
|
4542
|
-
const groupedRows = () => {
|
|
4209
|
+
let rows;
|
|
4210
|
+
if (groupByTicket) {
|
|
4543
4211
|
const groups = /* @__PURE__ */ new Map();
|
|
4544
|
-
for (const
|
|
4545
|
-
const key =
|
|
4546
|
-
const
|
|
4547
|
-
|
|
4548
|
-
|
|
4212
|
+
for (const test of visible) {
|
|
4213
|
+
const key = test.ticketId?.trim() || "";
|
|
4214
|
+
const group = groups.get(key) ?? [];
|
|
4215
|
+
group.push(test);
|
|
4216
|
+
groups.set(key, group);
|
|
4549
4217
|
}
|
|
4550
|
-
const
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
const
|
|
4555
|
-
const header =
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4218
|
+
const sortedKeys = [...groups.keys()].sort(
|
|
4219
|
+
(a, b) => a === "" ? 1 : b === "" ? -1 : a.localeCompare(b)
|
|
4220
|
+
);
|
|
4221
|
+
rows = sortedKeys.map((key) => {
|
|
4222
|
+
const group = groups.get(key);
|
|
4223
|
+
const header = `<div class="ticket-group-header">${key ? escHtml(key) : t("TEST_EDITOR.NO_TICKET")}</div>`;
|
|
4224
|
+
const groupRows = group.map((test) => {
|
|
4225
|
+
const i = visible.indexOf(test);
|
|
4226
|
+
return renderTestRow(test, i, state, t);
|
|
4227
|
+
}).join("");
|
|
4228
|
+
return `<div class="ticket-group">${header}${groupRows}</div>`;
|
|
4560
4229
|
}).join("");
|
|
4561
|
-
}
|
|
4562
|
-
|
|
4230
|
+
} else {
|
|
4231
|
+
rows = visible.map((test, i) => renderTestRow(test, i, state, t)).join("");
|
|
4232
|
+
}
|
|
4563
4233
|
return `
|
|
4564
4234
|
<div class="toolbar">
|
|
4565
4235
|
${tagFilterHtml}
|
|
4566
|
-
<button class="btn-select${groupByTicket ? " active" : ""}" id="btn-group-ticket"
|
|
4236
|
+
<button class="btn-select${groupByTicket ? " active" : ""}" id="btn-group-ticket">
|
|
4237
|
+
${groupByTicket ? t("TEST_EDITOR.UNGROUP_TICKET") : t("TEST_EDITOR.GROUP_BY_TICKET")}
|
|
4238
|
+
</button>
|
|
4567
4239
|
<button class="btn-select${selectMode ? " active" : ""}" id="btn-select-mode">
|
|
4568
4240
|
${selectMode ? t("TEST_EDITOR.CANCEL_SELECT") : t("TEST_EDITOR.MULTI_SELECT")}
|
|
4569
4241
|
</button>
|
|
4570
4242
|
</div>
|
|
4571
4243
|
${describeBarHtml}
|
|
4572
4244
|
<div class="list">
|
|
4573
|
-
${
|
|
4245
|
+
${visible.length ? rows : `<div class="empty">${t("TEST_EDITOR.NO_TESTS")}</div>`}
|
|
4574
4246
|
</div>`;
|
|
4575
4247
|
}
|
|
4576
4248
|
|
|
@@ -4587,8 +4259,7 @@ var TestEditorElement = class extends HTMLElement {
|
|
|
4587
4259
|
selectedIds = /* @__PURE__ */ new Set();
|
|
4588
4260
|
describeName = "";
|
|
4589
4261
|
groupByTicket = false;
|
|
4590
|
-
|
|
4591
|
-
issueTrackerParams = {};
|
|
4262
|
+
issueTrackerConfig = { ...DEFAULT_ISSUE_TRACKER_CONFIG };
|
|
4592
4263
|
constructor() {
|
|
4593
4264
|
super();
|
|
4594
4265
|
this.shadow = this.attachShadow({ mode: "open" });
|
|
@@ -4598,17 +4269,7 @@ var TestEditorElement = class extends HTMLElement {
|
|
|
4598
4269
|
this.loadTests();
|
|
4599
4270
|
}
|
|
4600
4271
|
async loadTests() {
|
|
4601
|
-
|
|
4602
|
-
this.persistence.getAllTests(),
|
|
4603
|
-
this.persistence.getGeneralConfig()
|
|
4604
|
-
]);
|
|
4605
|
-
this.tests = tests;
|
|
4606
|
-
this.issueTrackerProviderId = config?.["issueTrackerProviderId"] ?? DEFAULT_ISSUE_TRACKER_PROVIDER_ID;
|
|
4607
|
-
this.issueTrackerParams = config?.["issueTrackerParams"] ?? {};
|
|
4608
|
-
this.render();
|
|
4609
|
-
}
|
|
4610
|
-
toggleGroupByTicket() {
|
|
4611
|
-
this.groupByTicket = !this.groupByTicket;
|
|
4272
|
+
this.tests = await this.persistence.getAllTests();
|
|
4612
4273
|
this.render();
|
|
4613
4274
|
}
|
|
4614
4275
|
async deleteTest(id) {
|
|
@@ -4629,6 +4290,10 @@ var TestEditorElement = class extends HTMLElement {
|
|
|
4629
4290
|
hasInterceptors(testId) {
|
|
4630
4291
|
return Array.isArray(this.interceptorsByTest[testId]) && this.interceptorsByTest[testId].length > 0;
|
|
4631
4292
|
}
|
|
4293
|
+
toggleGroupByTicket() {
|
|
4294
|
+
this.groupByTicket = !this.groupByTicket;
|
|
4295
|
+
this.render();
|
|
4296
|
+
}
|
|
4632
4297
|
toggleSelectMode() {
|
|
4633
4298
|
this.selectMode = !this.selectMode;
|
|
4634
4299
|
if (!this.selectMode) this.selectedIds.clear();
|
|
@@ -4683,12 +4348,6 @@ ${beforeEach}${itBlocks}
|
|
|
4683
4348
|
const tags = this.allTags;
|
|
4684
4349
|
const visible = this.visibleTests;
|
|
4685
4350
|
const selectedVisible = visible.filter((t) => this.selectedIds.has(t.id));
|
|
4686
|
-
const ticketUrlByTest = {};
|
|
4687
|
-
for (const test of visible) {
|
|
4688
|
-
if (test.ticketId) {
|
|
4689
|
-
ticketUrlByTest[test.id] = resolveTicketUrl(this.issueTrackerProviderId, this.issueTrackerParams, test.ticketId);
|
|
4690
|
-
}
|
|
4691
|
-
}
|
|
4692
4351
|
this.shadow.innerHTML = `<style>${TEST_EDITOR_STYLES}</style>${renderTestEditor({
|
|
4693
4352
|
tags,
|
|
4694
4353
|
visible,
|
|
@@ -4699,15 +4358,12 @@ ${beforeEach}${itBlocks}
|
|
|
4699
4358
|
describeName: this.describeName,
|
|
4700
4359
|
expandedIndex: this.expandedIndex,
|
|
4701
4360
|
interceptorsByTest: this.interceptorsByTest,
|
|
4361
|
+
locale: localeForLang(this.translation.getLang()),
|
|
4702
4362
|
groupByTicket: this.groupByTicket,
|
|
4703
|
-
|
|
4704
|
-
locale: localeForLang(this.translation.getLang())
|
|
4363
|
+
issueTrackerConfig: this.issueTrackerConfig
|
|
4705
4364
|
}, this.t.bind(this))}`;
|
|
4706
|
-
this.shadow.getElementById("btn-select-mode")?.addEventListener("click", () => this.toggleSelectMode());
|
|
4707
4365
|
this.shadow.getElementById("btn-group-ticket")?.addEventListener("click", () => this.toggleGroupByTicket());
|
|
4708
|
-
this.shadow.
|
|
4709
|
-
(el) => el.addEventListener("click", (ev) => ev.stopPropagation())
|
|
4710
|
-
);
|
|
4366
|
+
this.shadow.getElementById("btn-select-mode")?.addEventListener("click", () => this.toggleSelectMode());
|
|
4711
4367
|
this.shadow.querySelectorAll("[data-filter-tag]").forEach((el) => {
|
|
4712
4368
|
el.addEventListener("click", () => {
|
|
4713
4369
|
const tag = el.dataset["filterTag"] ?? "";
|
|
@@ -4771,26 +4427,16 @@ if (!customElements.get("test-editor")) {
|
|
|
4771
4427
|
|
|
4772
4428
|
// src/components/configuration/configuration.styles.ts
|
|
4773
4429
|
var CONFIGURATION_STYLES = `
|
|
4774
|
-
:host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }
|
|
4430
|
+
:host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; max-height: 70vh; overflow-y: auto; scrollbar-width: thin; scrollbar-color: #30363d transparent; }
|
|
4775
4431
|
* { box-sizing: border-box; }
|
|
4776
4432
|
|
|
4777
4433
|
/* \u2500\u2500 Grid container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
4778
|
-
/* The SweetAlert2 host clips overflow (overflow:hidden), so the grid owns its
|
|
4779
|
-
own scroll \u2014 otherwise the last cards fall below the fold with no scrollbar. */
|
|
4780
4434
|
.cfg-grid {
|
|
4781
4435
|
display: grid;
|
|
4782
4436
|
grid-template-columns: 1fr 1fr;
|
|
4783
4437
|
gap: 10px;
|
|
4784
4438
|
padding: 14px;
|
|
4785
|
-
max-height: 72vh;
|
|
4786
|
-
overflow-y: auto;
|
|
4787
|
-
scrollbar-width: thin;
|
|
4788
|
-
scrollbar-color: #30363d transparent;
|
|
4789
4439
|
}
|
|
4790
|
-
.cfg-grid::-webkit-scrollbar { width: 8px; }
|
|
4791
|
-
.cfg-grid::-webkit-scrollbar-thumb { background: #30363d; border-radius: 4px; }
|
|
4792
|
-
.cfg-grid::-webkit-scrollbar-thumb:hover { background: #484f58; }
|
|
4793
|
-
.cfg-grid::-webkit-scrollbar-track { background: transparent; }
|
|
4794
4440
|
|
|
4795
4441
|
/* \u2500\u2500 Cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
4796
4442
|
.card {
|
|
@@ -5004,33 +4650,8 @@ function renderExportOverlay(state, t) {
|
|
|
5004
4650
|
</div>
|
|
5005
4651
|
</div>`;
|
|
5006
4652
|
}
|
|
5007
|
-
var TRACKER_INPUT_STYLE = "flex:1;min-width:180px;padding:5px 8px;background:#161b22;border:1px solid #30363d;border-radius:5px;color:#c9d1d9;font-size:12px;outline:none";
|
|
5008
|
-
function renderIssueTrackerCard(state, t) {
|
|
5009
|
-
const { issueTrackerProviderId, issueTrackerParams } = state;
|
|
5010
|
-
const provider = findIssueTrackerProvider(issueTrackerProviderId) ?? ISSUE_TRACKER_PROVIDERS[0];
|
|
5011
|
-
const values = issueTrackerParams[provider.id] ?? {};
|
|
5012
|
-
const options = ISSUE_TRACKER_PROVIDERS.map(
|
|
5013
|
-
(p) => `<option value="${escAttr(p.id)}" ${provider.id === p.id ? "selected" : ""}>${escHtml(t(p.labelKey))}</option>`
|
|
5014
|
-
).join("");
|
|
5015
|
-
const fields = provider.fields.map((f) => `
|
|
5016
|
-
<div class="field-row">
|
|
5017
|
-
<span class="field-label">${escHtml(t(f.labelKey))}</span>
|
|
5018
|
-
<input type="text" data-tracker-field="${escAttr(f.key)}" value="${escAttr(values[f.key] ?? "")}"
|
|
5019
|
-
placeholder="${escAttr(t(f.placeholderKey))}" style="${TRACKER_INPUT_STYLE}" />
|
|
5020
|
-
</div>`).join("");
|
|
5021
|
-
return `
|
|
5022
|
-
<div class="card card-wide">
|
|
5023
|
-
<div class="card-hd">${t("CONFIG.ISSUE_TRACKER_SECTION")}</div>
|
|
5024
|
-
<div class="field-row">
|
|
5025
|
-
<span class="field-label">${t("CONFIG.ISSUE_TRACKER_LABEL")}</span>
|
|
5026
|
-
<select id="issue-tracker-provider">${options}</select>
|
|
5027
|
-
</div>
|
|
5028
|
-
${fields}
|
|
5029
|
-
<div class="check-sub issue-tracker-disclaimer" style="margin-top:8px">${t("CONFIG.ISSUE_TRACKER_DISCLAIMER")}</div>
|
|
5030
|
-
</div>`;
|
|
5031
|
-
}
|
|
5032
4653
|
function renderConfiguration(state, t) {
|
|
5033
|
-
const { selectedLanguage, advancedHttpConfig, fixtureMode, selectorStrategy, filesystemGranted, cypressFolderName, smartSelectorEnabled, startHidden, resumeTtlMinutes } = state;
|
|
4654
|
+
const { selectedLanguage, advancedHttpConfig, fixtureMode, selectorStrategy, filesystemGranted, cypressFolderName, smartSelectorEnabled, startHidden, resumeTtlMinutes, issueTrackerConfig } = state;
|
|
5034
4655
|
const langOptions = LANGS.map(
|
|
5035
4656
|
(l) => `<option value="${l.value}" ${selectedLanguage === l.value ? "selected" : ""}>${l.label}</option>`
|
|
5036
4657
|
).join("");
|
|
@@ -5151,8 +4772,33 @@ function renderConfiguration(state, t) {
|
|
|
5151
4772
|
</div>
|
|
5152
4773
|
</div>
|
|
5153
4774
|
|
|
5154
|
-
<!-- Issue
|
|
5155
|
-
|
|
4775
|
+
<!-- Issue Tracker -->
|
|
4776
|
+
<div class="card card-wide">
|
|
4777
|
+
<div class="card-hd">${t("CONFIG.ISSUE_TRACKER_SECTION")}</div>
|
|
4778
|
+
<label class="check-row">
|
|
4779
|
+
<input type="checkbox" id="issue-tracker-toggle" ${issueTrackerConfig.enabled ? "checked" : ""} />
|
|
4780
|
+
<div>
|
|
4781
|
+
<div class="check-title">${t("CONFIG.ISSUE_TRACKER_TITLE")}</div>
|
|
4782
|
+
<div class="check-sub">${t("CONFIG.ISSUE_TRACKER_SUB")}</div>
|
|
4783
|
+
</div>
|
|
4784
|
+
</label>
|
|
4785
|
+
${issueTrackerConfig.enabled ? `
|
|
4786
|
+
<div class="field-row" style="margin-top:10px">
|
|
4787
|
+
<span class="field-label">${t("CONFIG.ISSUE_TRACKER_PROVIDER")}</span>
|
|
4788
|
+
<select id="issue-tracker-provider">
|
|
4789
|
+
${Object.values(ISSUE_TRACKER_PRESETS).map(
|
|
4790
|
+
(p) => `<option value="${p.id}" ${issueTrackerConfig.provider === p.id ? "selected" : ""}>${escHtml(p.label)}</option>`
|
|
4791
|
+
).join("")}
|
|
4792
|
+
</select>
|
|
4793
|
+
</div>
|
|
4794
|
+
<div class="field-row" style="margin-top:8px">
|
|
4795
|
+
<span class="field-label">${t("CONFIG.ISSUE_TRACKER_BASE_URL")}</span>
|
|
4796
|
+
<input id="issue-tracker-base-url" type="text"
|
|
4797
|
+
placeholder="${escAttr(t("CONFIG.ISSUE_TRACKER_BASE_URL_PH"))}"
|
|
4798
|
+
value="${escAttr(issueTrackerConfig.baseUrl)}"
|
|
4799
|
+
style="flex:1;padding:5px 8px;background:#161b22;border:1px solid #30363d;border-radius:5px;color:#c9d1d9;font-size:12px;outline:none" />
|
|
4800
|
+
</div>` : ""}
|
|
4801
|
+
</div>
|
|
5156
4802
|
|
|
5157
4803
|
<!-- Data -->
|
|
5158
4804
|
<div class="card card-wide">
|
|
@@ -5182,13 +4828,12 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
5182
4828
|
smartSelectorEnabled = true;
|
|
5183
4829
|
startHidden = false;
|
|
5184
4830
|
resumeTtlMinutes = DEFAULT_RESUME_TTL_MINUTES;
|
|
5185
|
-
issueTrackerProviderId = DEFAULT_ISSUE_TRACKER_PROVIDER_ID;
|
|
5186
|
-
issueTrackerParams = {};
|
|
5187
4831
|
isExporting = false;
|
|
5188
4832
|
exportMode = "all";
|
|
5189
4833
|
exportTests = [];
|
|
5190
4834
|
exportSelectedIds = /* @__PURE__ */ new Set();
|
|
5191
4835
|
exportSelectedTags = /* @__PURE__ */ new Set();
|
|
4836
|
+
issueTrackerConfig = { ...DEFAULT_ISSUE_TRACKER_CONFIG };
|
|
5192
4837
|
filesystemGranted = false;
|
|
5193
4838
|
cypressFolderName = null;
|
|
5194
4839
|
constructor() {
|
|
@@ -5225,12 +4870,11 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
5225
4870
|
this.filesystemGranted = config?.["allowReadWriteFiles"] === "true";
|
|
5226
4871
|
const handle = config?.["cypressDirectoryHandle"];
|
|
5227
4872
|
this.cypressFolderName = handle?.name ?? null;
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
}
|
|
4873
|
+
this.issueTrackerConfig = {
|
|
4874
|
+
enabled: config?.["issueTrackerEnabled"] === "true",
|
|
4875
|
+
provider: config?.["issueTrackerProvider"] ?? DEFAULT_ISSUE_TRACKER_CONFIG.provider,
|
|
4876
|
+
baseUrl: config?.["issueTrackerBaseUrl"] ?? ""
|
|
4877
|
+
};
|
|
5234
4878
|
this.render();
|
|
5235
4879
|
}
|
|
5236
4880
|
async onLanguageChange(lang) {
|
|
@@ -5263,20 +4907,6 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
5263
4907
|
await this.persistence.setConfig({ [RESUME_TTL_CONFIG_KEY]: safe });
|
|
5264
4908
|
this.render();
|
|
5265
4909
|
}
|
|
5266
|
-
/** Selects the issue-tracker provider (link-only, no sync — spec 014). */
|
|
5267
|
-
async onIssueTrackerProviderChange(id) {
|
|
5268
|
-
this.issueTrackerProviderId = id;
|
|
5269
|
-
await this.persistence.setConfig({ issueTrackerProviderId: id });
|
|
5270
|
-
this.render();
|
|
5271
|
-
}
|
|
5272
|
-
/** Stores a provider field value, scoped to the active provider so switching keeps values. */
|
|
5273
|
-
async onIssueTrackerParamChange(fieldKey, value) {
|
|
5274
|
-
const providerId = this.issueTrackerProviderId;
|
|
5275
|
-
const current = { ...this.issueTrackerParams[providerId] ?? {} };
|
|
5276
|
-
current[fieldKey] = value;
|
|
5277
|
-
this.issueTrackerParams = { ...this.issueTrackerParams, [providerId]: current };
|
|
5278
|
-
await this.persistence.setConfig({ issueTrackerParams: this.issueTrackerParams });
|
|
5279
|
-
}
|
|
5280
4910
|
onResetWidgetPosition() {
|
|
5281
4911
|
this.dispatchEvent(new CustomEvent("resetwidgetposition", { bubbles: true, composed: true }));
|
|
5282
4912
|
showToast(this.t("CONFIG.WIDGET_POSITION_RESET_DONE"));
|
|
@@ -5293,6 +4923,23 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
5293
4923
|
this.dispatchEvent(new CustomEvent("selectorstrategychange", { detail: strategy, bubbles: true, composed: true }));
|
|
5294
4924
|
this.render();
|
|
5295
4925
|
}
|
|
4926
|
+
async onIssueTrackerEnabledChange(enabled) {
|
|
4927
|
+
this.issueTrackerConfig = { ...this.issueTrackerConfig, enabled };
|
|
4928
|
+
await this.persistence.setConfig({ issueTrackerEnabled: enabled ? "true" : "false" });
|
|
4929
|
+
this.dispatchEvent(new CustomEvent("issuetrackerchange", { detail: { ...this.issueTrackerConfig }, bubbles: true, composed: true }));
|
|
4930
|
+
this.render();
|
|
4931
|
+
}
|
|
4932
|
+
async onIssueTrackerProviderChange(provider) {
|
|
4933
|
+
this.issueTrackerConfig = { ...this.issueTrackerConfig, provider };
|
|
4934
|
+
await this.persistence.setConfig({ issueTrackerProvider: provider });
|
|
4935
|
+
this.dispatchEvent(new CustomEvent("issuetrackerchange", { detail: { ...this.issueTrackerConfig }, bubbles: true, composed: true }));
|
|
4936
|
+
this.render();
|
|
4937
|
+
}
|
|
4938
|
+
async onIssueTrackerBaseUrlChange(baseUrl) {
|
|
4939
|
+
this.issueTrackerConfig = { ...this.issueTrackerConfig, baseUrl };
|
|
4940
|
+
await this.persistence.setConfig({ issueTrackerBaseUrl: baseUrl });
|
|
4941
|
+
this.dispatchEvent(new CustomEvent("issuetrackerchange", { detail: { ...this.issueTrackerConfig }, bubbles: true, composed: true }));
|
|
4942
|
+
}
|
|
5296
4943
|
async changeFolder() {
|
|
5297
4944
|
try {
|
|
5298
4945
|
await this.persistence.requestDirectoryPermissions();
|
|
@@ -5390,13 +5037,12 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
5390
5037
|
smartSelectorEnabled: this.smartSelectorEnabled,
|
|
5391
5038
|
startHidden: this.startHidden,
|
|
5392
5039
|
resumeTtlMinutes: this.resumeTtlMinutes,
|
|
5393
|
-
issueTrackerProviderId: this.issueTrackerProviderId,
|
|
5394
|
-
issueTrackerParams: this.issueTrackerParams,
|
|
5395
5040
|
isExporting: this.isExporting,
|
|
5396
5041
|
exportMode: this.exportMode,
|
|
5397
5042
|
exportTests: this.exportTests,
|
|
5398
5043
|
exportSelectedIds: this.exportSelectedIds,
|
|
5399
|
-
exportSelectedTags: this.exportSelectedTags
|
|
5044
|
+
exportSelectedTags: this.exportSelectedTags,
|
|
5045
|
+
issueTrackerConfig: this.issueTrackerConfig
|
|
5400
5046
|
}, this.t.bind(this))}`;
|
|
5401
5047
|
;
|
|
5402
5048
|
this.shadow.getElementById("lang-select").addEventListener(
|
|
@@ -5428,15 +5074,18 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
5428
5074
|
"change",
|
|
5429
5075
|
(e) => this.onSelectorStrategyChange(e.target.value)
|
|
5430
5076
|
);
|
|
5077
|
+
;
|
|
5078
|
+
this.shadow.getElementById("issue-tracker-toggle")?.addEventListener(
|
|
5079
|
+
"change",
|
|
5080
|
+
(e) => this.onIssueTrackerEnabledChange(e.target.checked)
|
|
5081
|
+
);
|
|
5431
5082
|
this.shadow.getElementById("issue-tracker-provider")?.addEventListener(
|
|
5432
5083
|
"change",
|
|
5433
5084
|
(e) => this.onIssueTrackerProviderChange(e.target.value)
|
|
5434
5085
|
);
|
|
5435
|
-
this.shadow.
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
() => this.onIssueTrackerParamChange(el.dataset["trackerField"] ?? "", el.value)
|
|
5439
|
-
)
|
|
5086
|
+
this.shadow.getElementById("issue-tracker-base-url")?.addEventListener(
|
|
5087
|
+
"change",
|
|
5088
|
+
(e) => this.onIssueTrackerBaseUrlChange(e.target.value)
|
|
5440
5089
|
);
|
|
5441
5090
|
this.shadow.getElementById("btn-change-folder")?.addEventListener("click", () => this.changeFolder());
|
|
5442
5091
|
this.shadow.getElementById("btn-revoke")?.addEventListener("click", () => this.revokeAccess());
|
|
@@ -6040,9 +5689,6 @@ var FILE_PREVIEW_STYLES = `
|
|
|
6040
5689
|
.file-name { flex: 1; font-size: 12px; color: #8b949e;
|
|
6041
5690
|
font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; }
|
|
6042
5691
|
.body { display: flex; flex: 1; overflow: hidden; min-height: 0; }
|
|
6043
|
-
/* Host for the CodeMirror editor (or the textarea fallback). */
|
|
6044
|
-
.editor-host { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }
|
|
6045
|
-
.editor-host .cm-editor { flex: 1; min-height: 0; }
|
|
6046
5692
|
.editor {
|
|
6047
5693
|
flex: 1; min-width: 0; padding: 14px;
|
|
6048
5694
|
background: #0d1117; color: #c9d1d9; border: none; outline: none;
|
|
@@ -6232,7 +5878,7 @@ function renderFilePreview(state, t) {
|
|
|
6232
5878
|
<button id="btn-copy" title="${t("FILE_PREVIEW.COPY_TITLE")}">\u{1F4CB}</button>
|
|
6233
5879
|
</div>
|
|
6234
5880
|
<div class="body">
|
|
6235
|
-
${showDiff ? `<div class="diff-panel" id="diff-panel">${buildDiffHtml(originalContent ?? "", currentContent, t)}</div>` : `<
|
|
5881
|
+
${showDiff ? `<div class="diff-panel" id="diff-panel">${buildDiffHtml(originalContent ?? "", currentContent, t)}</div>` : `<textarea class="editor" id="editor" spellcheck="false">${escHtml(fileContent ?? "")}</textarea>`}
|
|
6236
5882
|
${blocksPanelHtml}
|
|
6237
5883
|
</div>
|
|
6238
5884
|
${runResultHtml}
|
|
@@ -6250,7 +5896,6 @@ function renderFilePreview(state, t) {
|
|
|
6250
5896
|
var FilePreviewElement = class extends HTMLElement {
|
|
6251
5897
|
shadow;
|
|
6252
5898
|
textarea = null;
|
|
6253
|
-
editor = null;
|
|
6254
5899
|
fileName = null;
|
|
6255
5900
|
closeLabel = "";
|
|
6256
5901
|
translation = translationService;
|
|
@@ -6276,29 +5921,20 @@ var FilePreviewElement = class extends HTMLElement {
|
|
|
6276
5921
|
if (!this.closeLabel) this.closeLabel = this.translation.translate("FILE_PREVIEW.CLOSE_BTN");
|
|
6277
5922
|
this.render();
|
|
6278
5923
|
}
|
|
6279
|
-
disconnectedCallback() {
|
|
6280
|
-
this.editor?.destroy();
|
|
6281
|
-
this.editor = null;
|
|
6282
|
-
}
|
|
6283
5924
|
t(key) {
|
|
6284
5925
|
return this.translation.translate(key);
|
|
6285
5926
|
}
|
|
6286
|
-
/** Current editor content (CodeMirror if upgraded, else the textarea/fallback). */
|
|
6287
|
-
currentValue() {
|
|
6288
|
-
return this.editor?.getValue() ?? this.textarea?.value ?? this._fileContent ?? "";
|
|
6289
|
-
}
|
|
6290
5927
|
get fileContent() {
|
|
6291
5928
|
return this._fileContent;
|
|
6292
5929
|
}
|
|
6293
5930
|
set fileContent(v) {
|
|
6294
5931
|
if (this._originalContent === null) this._originalContent = v;
|
|
6295
5932
|
this._fileContent = v;
|
|
6296
|
-
if (this.
|
|
6297
|
-
else if (this.textarea) this.textarea.value = v ?? "";
|
|
5933
|
+
if (this.textarea) this.textarea.value = v ?? "";
|
|
6298
5934
|
else this.render();
|
|
6299
5935
|
}
|
|
6300
5936
|
saveFile() {
|
|
6301
|
-
const content = this.
|
|
5937
|
+
const content = this.textarea?.value ?? this._fileContent ?? "";
|
|
6302
5938
|
this.dispatchEvent(new CustomEvent("save", { detail: content, bubbles: true, composed: true }));
|
|
6303
5939
|
}
|
|
6304
5940
|
onClose() {
|
|
@@ -6347,7 +5983,7 @@ var FilePreviewElement = class extends HTMLElement {
|
|
|
6347
5983
|
* (and warns) when the file has no valid describe() block to insert into.
|
|
6348
5984
|
*/
|
|
6349
5985
|
insertBlocks() {
|
|
6350
|
-
const base = this.
|
|
5986
|
+
const base = this.textarea?.value ?? this._fileContent ?? "";
|
|
6351
5987
|
let content = base;
|
|
6352
5988
|
if (this.interceptorsBlock) {
|
|
6353
5989
|
const merged = advancedTestTransformationService.insertBeforeEach(content, this.interceptorsBlock);
|
|
@@ -6367,14 +6003,12 @@ var FilePreviewElement = class extends HTMLElement {
|
|
|
6367
6003
|
showToast(this.t("FILE_PREVIEW.INSERT_DONE"));
|
|
6368
6004
|
}
|
|
6369
6005
|
render() {
|
|
6370
|
-
this.editor?.destroy();
|
|
6371
|
-
this.editor = null;
|
|
6372
6006
|
this.shadow.innerHTML = `<style>${FILE_PREVIEW_STYLES}</style>${renderFilePreview({
|
|
6373
6007
|
fileName: this.fileName,
|
|
6374
6008
|
showDiff: this._showDiff,
|
|
6375
6009
|
fileContent: this._fileContent,
|
|
6376
6010
|
originalContent: this._originalContent,
|
|
6377
|
-
currentContent: this._fileContent ?? "",
|
|
6011
|
+
currentContent: this.textarea?.value ?? this._fileContent ?? "",
|
|
6378
6012
|
itBlock: this.itBlock,
|
|
6379
6013
|
interceptorsBlock: this.interceptorsBlock,
|
|
6380
6014
|
closeLabel: this.closeLabel,
|
|
@@ -6388,13 +6022,12 @@ var FilePreviewElement = class extends HTMLElement {
|
|
|
6388
6022
|
this.textarea.addEventListener("input", () => {
|
|
6389
6023
|
this._fileContent = ta.value;
|
|
6390
6024
|
});
|
|
6391
|
-
void this.upgradeEditor();
|
|
6392
6025
|
}
|
|
6393
6026
|
this.shadow.getElementById("btn-save")?.addEventListener("click", () => this.saveFile());
|
|
6394
6027
|
this.shadow.getElementById("btn-close")?.addEventListener("click", () => this.onClose());
|
|
6395
6028
|
this.shadow.getElementById("btn-launch")?.addEventListener("click", () => this.launchTest());
|
|
6396
6029
|
this.shadow.getElementById("btn-copy")?.addEventListener("click", () => {
|
|
6397
|
-
this.copyToClipboard(this.
|
|
6030
|
+
this.copyToClipboard(this.textarea?.value ?? this._fileContent ?? "");
|
|
6398
6031
|
});
|
|
6399
6032
|
this.shadow.getElementById("btn-diff")?.addEventListener("click", () => this.toggleDiff());
|
|
6400
6033
|
this.shadow.getElementById("btn-insert")?.addEventListener("click", () => this.insertBlocks());
|
|
@@ -6405,34 +6038,6 @@ var FilePreviewElement = class extends HTMLElement {
|
|
|
6405
6038
|
this.copyToClipboard(this.interceptorsBlock);
|
|
6406
6039
|
});
|
|
6407
6040
|
}
|
|
6408
|
-
/**
|
|
6409
|
-
* Lazily upgrades the textarea to a CodeMirror editor (syntax highlight +
|
|
6410
|
-
* Cypress autocomplete). On any failure the textarea is left in place, so the
|
|
6411
|
-
* editor degrades gracefully when CodeMirror can't load.
|
|
6412
|
-
*/
|
|
6413
|
-
async upgradeEditor() {
|
|
6414
|
-
const host = this.shadow.getElementById("editor-host");
|
|
6415
|
-
const ta = this.textarea;
|
|
6416
|
-
if (!host || !ta) return;
|
|
6417
|
-
try {
|
|
6418
|
-
const handle = await createCodeEditor({
|
|
6419
|
-
parent: host,
|
|
6420
|
-
root: this.shadow,
|
|
6421
|
-
doc: this._fileContent ?? "",
|
|
6422
|
-
onChange: (value) => {
|
|
6423
|
-
this._fileContent = value;
|
|
6424
|
-
}
|
|
6425
|
-
});
|
|
6426
|
-
if (!host.isConnected) {
|
|
6427
|
-
handle.destroy();
|
|
6428
|
-
return;
|
|
6429
|
-
}
|
|
6430
|
-
ta.remove();
|
|
6431
|
-
this.textarea = null;
|
|
6432
|
-
this.editor = handle;
|
|
6433
|
-
} catch {
|
|
6434
|
-
}
|
|
6435
|
-
}
|
|
6436
6041
|
};
|
|
6437
6042
|
if (!customElements.get("file-preview")) {
|
|
6438
6043
|
customElements.define("file-preview", FilePreviewElement);
|
|
@@ -6789,6 +6394,26 @@ function renderRecorderWidget(rec, paused, t) {
|
|
|
6789
6394
|
<div class="rec-badge">${paused ? t("RECORDER.BADGE_PAUSED") : t("RECORDER.BADGE_REC")}</div>`;
|
|
6790
6395
|
}
|
|
6791
6396
|
|
|
6397
|
+
// src/utils/fixture-convert.utils.ts
|
|
6398
|
+
function toFixtureInterceptors(interceptors, fixtures) {
|
|
6399
|
+
const fixtureNames = new Set(fixtures.map((f) => f.name));
|
|
6400
|
+
return interceptors.map((icp) => {
|
|
6401
|
+
const match = icp.match(/\.as\('([^']+)'\)$/);
|
|
6402
|
+
if (!match) return icp;
|
|
6403
|
+
const fixtureFile = `${match[1]}.json`;
|
|
6404
|
+
if (!fixtureNames.has(fixtureFile)) return icp;
|
|
6405
|
+
return icp.replace(/\)\.as\(/, `, { fixture: '${fixtureFile}' }).as(`);
|
|
6406
|
+
});
|
|
6407
|
+
}
|
|
6408
|
+
function simplifyFixtureWaits(commands, fixtures) {
|
|
6409
|
+
const fixtureAliases = new Set(fixtures.map((f) => f.name.replace(/\.json$/, "")));
|
|
6410
|
+
return commands.map((cmd) => {
|
|
6411
|
+
const match = cmd.match(/^cy\.wait\('@([^']+)'\)/);
|
|
6412
|
+
if (!match || !fixtureAliases.has(match[1])) return cmd;
|
|
6413
|
+
return `cy.wait('@${match[1]}').then((interception) => { })`;
|
|
6414
|
+
});
|
|
6415
|
+
}
|
|
6416
|
+
|
|
6792
6417
|
// src/components/lib-e2e-recorder/lib-e2e-recorder.ts
|
|
6793
6418
|
var LibE2eRecorderElement = class extends HTMLElement {
|
|
6794
6419
|
shadow;
|
|
@@ -6815,6 +6440,7 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
6815
6440
|
httpMonitor;
|
|
6816
6441
|
smartSelectorEnabled = true;
|
|
6817
6442
|
_needsRecordingRebuild = false;
|
|
6443
|
+
issueTrackerConfig = { ...DEFAULT_ISSUE_TRACKER_CONFIG };
|
|
6818
6444
|
recording;
|
|
6819
6445
|
persistence;
|
|
6820
6446
|
translation;
|
|
@@ -6958,6 +6584,11 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
6958
6584
|
const strategy = config?.["selectorStrategy"];
|
|
6959
6585
|
if (strategy) this.recording.selectorStrategy = strategy;
|
|
6960
6586
|
this.smartSelectorEnabled = config?.["smartSelectorEnabled"] !== "false";
|
|
6587
|
+
this.issueTrackerConfig = {
|
|
6588
|
+
enabled: config?.["issueTrackerEnabled"] === "true",
|
|
6589
|
+
provider: config?.["issueTrackerProvider"] ?? DEFAULT_ISSUE_TRACKER_CONFIG.provider,
|
|
6590
|
+
baseUrl: config?.["issueTrackerBaseUrl"] ?? ""
|
|
6591
|
+
};
|
|
6961
6592
|
}
|
|
6962
6593
|
// ── cross-app session continuity (spec 006) ───────────────────────────────
|
|
6963
6594
|
/**
|
|
@@ -7383,6 +7014,7 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
7383
7014
|
const child = document.createElement("test-editor");
|
|
7384
7015
|
child.persistence = this.persistence;
|
|
7385
7016
|
child.translation = this.translation;
|
|
7017
|
+
child.issueTrackerConfig = this.issueTrackerConfig;
|
|
7386
7018
|
container.appendChild(child);
|
|
7387
7019
|
},
|
|
7388
7020
|
willClose: () => {
|
|
@@ -7408,19 +7040,16 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
7408
7040
|
if (!container) return;
|
|
7409
7041
|
const child = document.createElement("save-test");
|
|
7410
7042
|
child.translation = this.translation;
|
|
7411
|
-
|
|
7412
|
-
const providerId = config?.["issueTrackerProviderId"];
|
|
7413
|
-
if (providerId) child.issueTrackerProviderId = providerId;
|
|
7414
|
-
});
|
|
7043
|
+
child.issueTrackerConfig = this.issueTrackerConfig;
|
|
7415
7044
|
container.appendChild(child);
|
|
7416
7045
|
child.addEventListener("savetest", (e) => {
|
|
7417
7046
|
const { description, notes, tags, ticketId } = e.detail ?? {};
|
|
7418
|
-
this.onSaveTest(description ?? null, tags ?? [], notes ?? "", ticketId ??
|
|
7047
|
+
this.onSaveTest(description ?? null, tags ?? [], notes ?? "", ticketId ?? "");
|
|
7419
7048
|
import_sweetalert2.default.close();
|
|
7420
7049
|
});
|
|
7421
7050
|
child.addEventListener("saveandexport", (e) => {
|
|
7422
7051
|
const { description, notes, tags, ticketId } = e.detail ?? {};
|
|
7423
|
-
this.onSaveAndExportTest(description ?? null, tags ?? [], notes ?? "", ticketId ??
|
|
7052
|
+
this.onSaveAndExportTest(description ?? null, tags ?? [], notes ?? "", ticketId ?? "");
|
|
7424
7053
|
import_sweetalert2.default.close();
|
|
7425
7054
|
});
|
|
7426
7055
|
},
|
|
@@ -7456,6 +7085,9 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
7456
7085
|
this.style.display = this.isVisible ? "" : "none";
|
|
7457
7086
|
});
|
|
7458
7087
|
child.addEventListener("resetwidgetposition", () => this.resetWidgetPosition());
|
|
7088
|
+
child.addEventListener("issuetrackerchange", (e) => {
|
|
7089
|
+
this.issueTrackerConfig = e.detail;
|
|
7090
|
+
});
|
|
7459
7091
|
},
|
|
7460
7092
|
willClose: () => {
|
|
7461
7093
|
this.isSettingsDialogOpen = false;
|
|
@@ -7608,38 +7240,36 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
7608
7240
|
this.resizePopup();
|
|
7609
7241
|
}
|
|
7610
7242
|
// ── save handlers ─────────────────────────────────────────────────────────
|
|
7611
|
-
async onSaveTest(description, tags = [], notes = "", ticketId =
|
|
7612
|
-
if (description)
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
/** Writes captured fixtures to cypress/fixtures and toasts the outcome (spec 012). */
|
|
7635
|
-
async writeFixturesIfAny(fixtures) {
|
|
7636
|
-
if (!fixtures.length) return;
|
|
7637
|
-
try {
|
|
7638
|
-
const n = await this.persistence.writeFixtures(fixtures);
|
|
7639
|
-
showToast(`${this.translation.translate("RECORDER.FIXTURES_WRITTEN_TOAST")} (${n})`);
|
|
7640
|
-
} catch {
|
|
7641
|
-
showToast(this.translation.translate("RECORDER.FIXTURES_NO_FOLDER_TOAST"), false);
|
|
7243
|
+
async onSaveTest(description, tags = [], notes = "", ticketId = "") {
|
|
7244
|
+
if (!description) return;
|
|
7245
|
+
await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags, notes, ticketId || void 0);
|
|
7246
|
+
this.recording.clearCommands();
|
|
7247
|
+
this.clearRecordingHistory();
|
|
7248
|
+
this.cypressCommands = [];
|
|
7249
|
+
this.interceptors = [];
|
|
7250
|
+
}
|
|
7251
|
+
async onSaveAndExportTest(description, tags = [], notes = "", ticketId = "") {
|
|
7252
|
+
if (!description) return;
|
|
7253
|
+
const fixtures = this.recording.getFixturesSnapshot();
|
|
7254
|
+
const isFixtureMode = this.httpMonitor?.isFixtureModeEnabled() ?? false;
|
|
7255
|
+
let finalInterceptors = this.interceptors;
|
|
7256
|
+
let finalCommands = this.cypressCommands;
|
|
7257
|
+
if (isFixtureMode && fixtures.length > 0) {
|
|
7258
|
+
try {
|
|
7259
|
+
const n = await this.persistence.writeFixtures(fixtures);
|
|
7260
|
+
finalInterceptors = toFixtureInterceptors(this.interceptors, fixtures);
|
|
7261
|
+
finalCommands = simplifyFixtureWaits(this.cypressCommands, fixtures);
|
|
7262
|
+
showToast(`${this.translation.translate("RECORDER.FIXTURES_WRITTEN_TOAST")} (${n})`);
|
|
7263
|
+
} catch {
|
|
7264
|
+
showToast(this.translation.translate("RECORDER.FIXTURES_NO_FOLDER_TOAST"), false);
|
|
7265
|
+
}
|
|
7642
7266
|
}
|
|
7267
|
+
const id = await this.persistence.insertTest(description, finalCommands, finalInterceptors, tags, notes, ticketId || void 0);
|
|
7268
|
+
this.recording.clearCommands();
|
|
7269
|
+
this.clearRecordingHistory();
|
|
7270
|
+
this.cypressCommands = [];
|
|
7271
|
+
this.interceptors = [];
|
|
7272
|
+
setTimeout(() => this.showAdvancedEditorDialog(id), 300);
|
|
7643
7273
|
}
|
|
7644
7274
|
// ── helpers ───────────────────────────────────────────────────────────────
|
|
7645
7275
|
toggleModal(flag, openFn) {
|
|
@@ -7685,26 +7315,21 @@ if (!customElements.get("lib-e2e-recorder")) {
|
|
|
7685
7315
|
}
|
|
7686
7316
|
|
|
7687
7317
|
// src/index.ts
|
|
7688
|
-
var VERSION = "0.
|
|
7318
|
+
var VERSION = "0.9.0";
|
|
7689
7319
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7690
7320
|
0 && (module.exports = {
|
|
7691
7321
|
ACTIVE_SESSION_BREADCRUMB_KEY,
|
|
7692
7322
|
AdvancedTestEditorElement,
|
|
7693
7323
|
AdvancedTestTransformationService,
|
|
7694
|
-
CHAIN_METHODS,
|
|
7695
|
-
CYPRESS_COMPLETIONS,
|
|
7696
|
-
CY_METHODS,
|
|
7697
7324
|
ConfigurationElement,
|
|
7698
7325
|
DB_SCHEMA,
|
|
7699
7326
|
DB_STORE_NAMES,
|
|
7700
|
-
DEFAULT_ISSUE_TRACKER_PROVIDER_ID,
|
|
7701
7327
|
DEFAULT_RESUME_TTL_MINUTES,
|
|
7702
7328
|
DRAG_THRESHOLD,
|
|
7703
7329
|
FilePreviewElement,
|
|
7704
7330
|
HelpPanelElement,
|
|
7705
7331
|
HttpMonitor,
|
|
7706
7332
|
INPUT_TYPES,
|
|
7707
|
-
ISSUE_TRACKER_PROVIDERS,
|
|
7708
7333
|
LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES,
|
|
7709
7334
|
LOCALE_BY_LANG,
|
|
7710
7335
|
LibE2eRecorderElement,
|
|
@@ -7717,7 +7342,6 @@ var VERSION = "0.8.0";
|
|
|
7717
7342
|
SelectorPickerElement,
|
|
7718
7343
|
Subject,
|
|
7719
7344
|
TOGGLE_MARGIN,
|
|
7720
|
-
TOP_LEVEL,
|
|
7721
7345
|
TestEditorElement,
|
|
7722
7346
|
TestPrevisualizerElement,
|
|
7723
7347
|
TransformationService,
|
|
@@ -7726,14 +7350,8 @@ var VERSION = "0.8.0";
|
|
|
7726
7350
|
advancedTestTransformationService,
|
|
7727
7351
|
boxOffsetForDirection,
|
|
7728
7352
|
boxTopLeftFor,
|
|
7729
|
-
buildTicketComment,
|
|
7730
|
-
buildTicketUrl,
|
|
7731
7353
|
clampTogglePosition,
|
|
7732
|
-
createCodeEditor,
|
|
7733
7354
|
defaultTogglePosition,
|
|
7734
|
-
filterCompletions,
|
|
7735
|
-
filterCypressCompletions,
|
|
7736
|
-
findIssueTrackerProvider,
|
|
7737
7355
|
generateAlias,
|
|
7738
7356
|
inferAssertionCommand,
|
|
7739
7357
|
injectStyles,
|
|
@@ -7745,7 +7363,6 @@ var VERSION = "0.8.0";
|
|
|
7745
7363
|
makeSwalDraggableByContentId,
|
|
7746
7364
|
persistenceService,
|
|
7747
7365
|
resolveExpandDirection,
|
|
7748
|
-
resolveTicketUrl,
|
|
7749
7366
|
selectTestsForExport,
|
|
7750
7367
|
setSwal2DataCyAttribute,
|
|
7751
7368
|
showToast,
|