lib-e2e-cypress-for-dummys-ts 0.2.0 → 0.3.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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/models/lang.model.ts","../src/models/input-types.model.ts","../src/models/db-schema.model.ts","../src/i18n/es.ts","../src/i18n/en.ts","../src/i18n/fr.ts","../src/i18n/it.ts","../src/i18n/de.ts","../src/services/translation.service.ts","../src/services/transformation.service.ts","../src/services/advanced-test.transformation.service.ts","../src/utils/subject.ts","../src/services/recording.service.ts","../src/services/persistence.service.ts","../src/services/http-monitor.ts","../src/utils/styles.utils.ts","../src/utils/modal.utils.ts","../src/utils/toast.utils.ts","../src/components/test-previsualizer/test-previsualizer.styles.ts","../src/components/test-previsualizer/test-previsualizer.template.ts","../src/components/test-previsualizer/test-previsualizer.ts","../src/components/save-test/save-test.styles.ts","../src/components/save-test/save-test.template.ts","../src/components/save-test/save-test.ts","../src/components/test-editor/test-editor.styles.ts","../src/components/test-editor/test-editor.template.ts","../src/components/test-editor/test-editor.ts","../src/components/configuration/configuration.styles.ts","../src/components/configuration/configuration.template.ts","../src/components/configuration/configuration.ts","../src/components/advanced-test-editor/advanced-test-editor.styles.ts","../src/components/advanced-test-editor/advanced-test-editor.template.ts","../src/components/advanced-test-editor/advanced-test-editor.ts","../src/components/file-preview/file-preview.styles.ts","../src/components/file-preview/file-preview.template.ts","../src/components/file-preview/file-preview.ts","../src/components/lib-e2e-recorder/lib-e2e-recorder.ts","../src/components/lib-e2e-recorder/lib-e2e-recorder.styles.ts","../src/components/lib-e2e-recorder/lib-e2e-recorder.template.ts","../src/index.ts"],"sourcesContent":["export type Lang = 'es' | 'en' | 'fr' | 'it' | 'de';\r\n\r\nexport const SUPPORTED_LANGS: Lang[] = ['es', 'en', 'fr', 'it', 'de'];\r\n\r\nexport function isLang(value: string): value is Lang {\r\n return SUPPORTED_LANGS.includes(value as Lang);\r\n}\r\n","export const INPUT_TYPES = [\r\n 'text',\r\n 'password',\r\n 'email',\r\n 'search',\r\n 'tel',\r\n 'url',\r\n 'number',\r\n 'textarea',\r\n] as const;\r\n\r\nexport type InputType = (typeof INPUT_TYPES)[number];\r\n","export interface DBStoreIndex {\r\n name: string;\r\n keyPath: string;\r\n unique: boolean;\r\n}\r\n\r\nexport interface DBStore {\r\n name: string;\r\n keyPath: string;\r\n autoIncrement: boolean;\r\n indexes: DBStoreIndex[];\r\n}\r\n\r\nexport interface DBSchema {\r\n name: string;\r\n version: number;\r\n stores: DBStore[];\r\n}\r\n\r\nexport const DB_SCHEMA: DBSchema = {\r\n name: 'E2ECypressDB',\r\n version: 10,\r\n stores: [\r\n {\r\n name: 'tests',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'name', keyPath: 'name', unique: false },\r\n { name: 'createdAt', keyPath: 'createdAt', unique: false },\r\n ],\r\n },\r\n {\r\n name: 'commands',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'command', keyPath: 'command', unique: false },\r\n { name: 'testId', keyPath: 'testId', unique: false },\r\n { name: 'createdAt', keyPath: 'createdAt', unique: false },\r\n ],\r\n },\r\n {\r\n name: 'interceptors',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'interceptor', keyPath: 'interceptor', unique: false },\r\n { name: 'testId', keyPath: 'testId', unique: false },\r\n { name: 'createdAt', keyPath: 'createdAt', unique: false },\r\n ],\r\n },\r\n {\r\n name: 'configuration',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'language', keyPath: 'language', unique: false },\r\n { name: 'extendedHttpCommands', keyPath: 'extendedHttpCommands', unique: false },\r\n { name: 'allowReadWriteFiles', keyPath: 'allowReadWriteFiles', unique: false },\r\n ],\r\n },\r\n ],\r\n};\r\n\r\nexport const DB_STORE_NAMES = DB_SCHEMA.stores.map(s => s.name) as [\r\n 'tests',\r\n 'commands',\r\n 'interceptors',\r\n 'configuration',\r\n];\r\n","export const I18N_ES = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Configuración',\r\n SHOW_ADVANCED_EDITOR: 'Editor avanzado',\r\n DIALOG_SAVED_TESTS: 'Pruebas guardadas',\r\n DIALOG_COMMANDS: 'Previsualizador de comandos Cypress',\r\n DIALOG_SAVE: '¿Guardar la grabación?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Descripción de la prueba',\r\n CANCEL: 'Cancelar',\r\n ASK: '¿Guardar el test grabado?',\r\n YES_CONTINUE: 'Sí, continuar',\r\n NO_DISCARD: 'No, descartar',\r\n DESC_PLACEHOLDER: 'Ej: Login correcto con credenciales válidas',\r\n TAGS_LABEL: 'Etiquetas (opcional, para filtrar después):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regresión…',\r\n ADD_TAG: '+ Añadir',\r\n NO_TAGS: 'Sin etiquetas',\r\n SAVE_BTN: '💾 Guardar',\r\n SAVE_AND_EDIT: '📝 Guardar y editar',\r\n REMOVE_TAG_TITLE: 'Quitar',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Sin etiquetas',\r\n SELECTED_SINGULAR: 'seleccionado',\r\n SELECTED_PLURAL: 'seleccionados',\r\n DESCRIBE_PLACEHOLDER: 'Nombre del describe (opcional)',\r\n COPY_DESCRIBE: '🗂 Copiar describe()',\r\n MULTI_SELECT: '🗂 Multi-select',\r\n CANCEL_SELECT: '✕ Cancelar',\r\n SECTION_COMMANDS: 'Comandos',\r\n SECTION_INTERCEPTORS: 'Interceptores',\r\n COPY_CMDS_BTN: '📋 Copiar comandos',\r\n COPY_ICPS_BTN: '📋 Copiar interceptores',\r\n DEFAULT_DESCRIBE: 'Suite de tests',\r\n NO_TESTS: 'No hay tests guardados',\r\n DELETE_TITLE: 'Eliminar',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Idioma',\r\n LANG_FIELD: 'Interfaz',\r\n HTTP_SECTION: '⚡ HTTP Avanzado',\r\n HTTP_TITLE: 'Validaciones de body',\r\n HTTP_SUB: 'GET → response · POST/PUT → request',\r\n SELECTOR_SECTION: '🎯 Estrategia de selector',\r\n SELECTOR_LABEL: 'Atributo preferido para cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (por defecto)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#elemento)',\r\n SELECTOR_HINT: 'El grabador buscará este atributo primero. Si no existe, intentará los demás.',\r\n FOLDER_SECTION: '📁 Carpeta Cypress',\r\n FOLDER_CONNECTED: 'conectado —',\r\n FOLDER_NOT_SET: 'sin configurar',\r\n FOLDER_CHANGE_BTN: '📁 Cambiar carpeta',\r\n FOLDER_SELECT_BTN: '📁 Seleccionar carpeta',\r\n FOLDER_REVOKE_BTN: '✕ Quitar acceso',\r\n DATA_SECTION: '💾 Datos',\r\n DATA_DESC: 'Exporta todos tus tests a JSON o importa una copia de seguridad.',\r\n EXPORT_BTN: '⬆️ Exportar tests',\r\n IMPORT_BTN: '⬇️ Importar tests',\r\n FOLDER_UPDATED_TOAST: '✓ Carpeta de Cypress actualizada',\r\n FOLDER_ERROR_TOAST: 'Error al acceder a la carpeta',\r\n IMPORT_SUCCESS: 'Datos importados correctamente.',\r\n IMPORT_ERROR: 'Error al importar.',\r\n JSON_INVALID: 'El archivo no es un JSON válido.',\r\n JSON_BAD_FORMAT: 'El archivo no tiene el formato esperado.',\r\n SMART_SELECTOR_SECTION: '🔍 Selector inteligente',\r\n SMART_SELECTOR_TITLE: 'Selector inteligente',\r\n SMART_SELECTOR_SUB: 'Muestra un picker al hacer click en elementos sin selector válido.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Selecciona un elemento del DOM',\r\n PREVIEW_LABEL: 'navegar',\r\n CONFIRM_HINT: 'confirmar',\r\n CANCEL_HINT: 'cancelar',\r\n QUALITY_EXCELLENT: 'Excelente — tiene atributo de prueba (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Bueno — tiene un id válido',\r\n QUALITY_ACCEPTABLE: 'Aceptable — solo tiene clases CSS',\r\n QUALITY_POOR: 'No recomendado — solo tag o estilo inline',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptores',\r\n COPY_CMDS_BTN: '📋 Copiar comandos',\r\n SHOW_INTERCEPTORS: '▼ Ver interceptores',\r\n HIDE_INTERCEPTORS: '▲ Ocultar interceptores',\r\n SECTION_COMMANDS: 'Comandos',\r\n NO_CMDS_YET: 'Sin comandos aún',\r\n NO_ICP_SHORT: 'Sin interceptores',\r\n COPY_ICP_BTN: '📋 Copiar interceptores',\r\n UP_TITLE: 'Subir',\r\n DOWN_TITLE: 'Bajar',\r\n DEL_TITLE: 'Eliminar',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Reactivar acceso',\r\n PERMISSION_EXPIRED: '🔑 El permiso ha caducado',\r\n PERMISSION_EXPIRED_HINT: 'Haz clic para reactivar el acceso a tu carpeta de Cypress.',\r\n NO_ACCESS: '🔒 Sin acceso a archivos locales',\r\n NO_ACCESS_HINT: 'Configura el acceso en ⚙️ Config.',\r\n NO_FILES: 'Sin archivos',\r\n SELECT_FILE: '← Selecciona un archivo del árbol',\r\n IT_LABEL: '🧪 it() a insertar:',\r\n COPY_IT_BTN: '📋 Copiar it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() interceptores:',\r\n COPY_ICP_BTN: '📋 Copiar interceptores',\r\n INSERT_BTN: '💾 Insertar en archivo',\r\n EDIT_MANUAL_BTN: '✏️ Editar manualmente',\r\n CLOSE_BTN: '✕ Cerrar',\r\n NEW_FILE_BTN: '+ Nuevo archivo',\r\n REFRESH_BTN: '↻ Actualizar',\r\n NEW_FILE_PLACEHOLDER: 'nombre-del-test',\r\n NEW_FILE_CONFIRM: 'Crear',\r\n NEW_FILE_CANCEL: 'Cancelar',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Sin archivo',\r\n COPY_TITLE: 'Copiar contenido del editor',\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copiar',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: 'Sin cambios respecto al original',\r\n NO_CHANGES_SHORT: 'Sin cambios',\r\n LAUNCH_BTN: '▶ Lanzar test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Guardar',\r\n CLOSE_BTN: '✕ Cerrar',\r\n BACK_TO_EDITOR: '← Volver al editor',\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Acceso a ficheros',\r\n FS_LATER_BTN: 'Ahora no',\r\n FS_SELECT_BTN: '📁 Seleccionar carpeta',\r\n FS_SUCCESS_TOAST: '✓ Carpeta de Cypress configurada',\r\n FS_ERROR_TOAST: 'Error al acceder a la carpeta',\r\n FS_INTRO_HTML: 'El <strong style=\"color:#e6edf3\">editor avanzado</strong> puede insertar tus tests directamente en los archivos <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> de Cypress.',\r\n FS_STRUCTURE_HINT_HTML: 'Selecciona la carpeta que contiene la subcarpeta <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code>. La extensión espera esta estructura:',\r\n FS_TREE_PICK_HINT: '← selecciona esta carpeta',\r\n FS_TREE_READ_HINT: '← la extensión leerá aquí',\r\n FS_PERMISSION_NOTE: 'El permiso se guarda en el navegador y no se vuelve a solicitar.',\r\n ASSERTION_SECTION: '➕ Añadir aserción',\r\n ASSERT_SELECTOR_PH: 'selector, ej: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'valor esperado',\r\n ASSERT_ADD_BTN: '➕ Añadir',\r\n FILE_EDITOR_TITLE: '✏️ Editor de archivo',\r\n FILE_SAVED_TOAST: '✓ Archivo guardado',\r\n FILE_SAVE_ERROR_TOAST: 'Error al guardar el archivo',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Ficheros',\r\n BTN_COMMANDS: 'Comandos',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pausar (Ctrl+P)',\r\n RESUME_TITLE: 'Reanudar (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSA',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Detener (Ctrl+R)',\r\n START_TITLE: 'Grabar (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_EN = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Settings',\r\n SHOW_ADVANCED_EDITOR: 'Advanced editor',\r\n DIALOG_SAVED_TESTS: 'Saved tests',\r\n DIALOG_COMMANDS: 'Cypress commands previewer',\r\n DIALOG_SAVE: 'Save recording?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Test description',\r\n CANCEL: 'Cancel',\r\n ASK: 'Save the recorded test?',\r\n YES_CONTINUE: 'Yes, continue',\r\n NO_DISCARD: 'No, discard',\r\n DESC_PLACEHOLDER: 'E.g.: Successful login with valid credentials',\r\n TAGS_LABEL: 'Tags (optional, for later filtering):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regression…',\r\n ADD_TAG: '+ Add',\r\n NO_TAGS: 'No tags',\r\n SAVE_BTN: '💾 Save',\r\n SAVE_AND_EDIT: '📝 Save and edit',\r\n REMOVE_TAG_TITLE: 'Remove',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'No tags',\r\n SELECTED_SINGULAR: 'selected',\r\n SELECTED_PLURAL: 'selected',\r\n DESCRIBE_PLACEHOLDER: 'describe name (optional)',\r\n COPY_DESCRIBE: '🗂 Copy describe()',\r\n MULTI_SELECT: '🗂 Multi-select',\r\n CANCEL_SELECT: '✕ Cancel',\r\n SECTION_COMMANDS: 'Commands',\r\n SECTION_INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Copy commands',\r\n COPY_ICPS_BTN: '📋 Copy interceptors',\r\n DEFAULT_DESCRIBE: 'Test suite',\r\n NO_TESTS: 'No saved tests',\r\n DELETE_TITLE: 'Delete',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Language',\r\n LANG_FIELD: 'Interface',\r\n HTTP_SECTION: '⚡ Advanced HTTP',\r\n HTTP_TITLE: 'Body validations',\r\n HTTP_SUB: 'GET → response · POST/PUT → request',\r\n SELECTOR_SECTION: '🎯 Selector strategy',\r\n SELECTOR_LABEL: 'Preferred attribute for cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (default)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#element)',\r\n SELECTOR_HINT: 'The recorder will look for this attribute first. If not found, it will try the others.',\r\n FOLDER_SECTION: '📁 Cypress Folder',\r\n FOLDER_CONNECTED: 'connected —',\r\n FOLDER_NOT_SET: 'not configured',\r\n FOLDER_CHANGE_BTN: '📁 Change folder',\r\n FOLDER_SELECT_BTN: '📁 Select folder',\r\n FOLDER_REVOKE_BTN: '✕ Revoke access',\r\n DATA_SECTION: '💾 Data',\r\n DATA_DESC: 'Export all your tests to JSON or import a backup.',\r\n EXPORT_BTN: '⬆️ Export tests',\r\n IMPORT_BTN: '⬇️ Import tests',\r\n FOLDER_UPDATED_TOAST: '✓ Cypress folder updated',\r\n FOLDER_ERROR_TOAST: 'Error accessing the folder',\r\n IMPORT_SUCCESS: 'Data imported successfully.',\r\n IMPORT_ERROR: 'Error importing.',\r\n JSON_INVALID: 'The file is not valid JSON.',\r\n JSON_BAD_FORMAT: 'The file does not have the expected format.',\r\n SMART_SELECTOR_SECTION: '🔍 Smart selector',\r\n SMART_SELECTOR_TITLE: 'Smart selector',\r\n SMART_SELECTOR_SUB: 'Shows a picker when clicking elements with no valid selector.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Select a DOM element',\r\n PREVIEW_LABEL: 'navigate',\r\n CONFIRM_HINT: 'confirm',\r\n CANCEL_HINT: 'cancel',\r\n QUALITY_EXCELLENT: 'Excellent — has a testing attribute (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Good — has a valid id',\r\n QUALITY_ACCEPTABLE: 'Acceptable — CSS classes only',\r\n QUALITY_POOR: 'Not recommended — tag name or inline style only',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Copy commands',\r\n SHOW_INTERCEPTORS: '▼ Show interceptors',\r\n HIDE_INTERCEPTORS: '▲ Hide interceptors',\r\n SECTION_COMMANDS: 'Commands',\r\n NO_CMDS_YET: 'No commands yet',\r\n NO_ICP_SHORT: 'No interceptors',\r\n COPY_ICP_BTN: '📋 Copy interceptors',\r\n UP_TITLE: 'Move up',\r\n DOWN_TITLE: 'Move down',\r\n DEL_TITLE: 'Delete',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Reactivate access',\r\n PERMISSION_EXPIRED: '🔑 Permission expired',\r\n PERMISSION_EXPIRED_HINT: 'Click to reactivate access to your Cypress folder.',\r\n NO_ACCESS: '🔒 No access to local files',\r\n NO_ACCESS_HINT: 'Configure access in ⚙️ Config.',\r\n NO_FILES: 'No files',\r\n SELECT_FILE: '← Select a file from the tree',\r\n IT_LABEL: '🧪 it() to insert:',\r\n COPY_IT_BTN: '📋 Copy it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() interceptors:',\r\n COPY_ICP_BTN: '📋 Copy interceptors',\r\n INSERT_BTN: '💾 Insert into file',\r\n EDIT_MANUAL_BTN: '✏️ Edit manually',\r\n CLOSE_BTN: '✕ Close',\r\n NEW_FILE_BTN: '+ New file',\r\n REFRESH_BTN: '↻ Refresh',\r\n NEW_FILE_PLACEHOLDER: 'test-name',\r\n NEW_FILE_CONFIRM: 'Create',\r\n NEW_FILE_CANCEL: 'Cancel',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'No file',\r\n COPY_TITLE: 'Copy editor content',\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copy',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: 'No changes from original',\r\n NO_CHANGES_SHORT: 'No changes',\r\n LAUNCH_BTN: '▶ Run test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Save',\r\n CLOSE_BTN: '✕ Close',\r\n BACK_TO_EDITOR: '← Back to editor',\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 File access',\r\n FS_LATER_BTN: 'Not now',\r\n FS_SELECT_BTN: '📁 Select folder',\r\n FS_SUCCESS_TOAST: '✓ Cypress folder configured',\r\n FS_ERROR_TOAST: 'Error accessing the folder',\r\n FS_INTRO_HTML: 'The <strong style=\"color:#e6edf3\">advanced editor</strong> can insert your tests directly into the Cypress <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> files.',\r\n FS_STRUCTURE_HINT_HTML: 'Select the folder that contains the <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code> subfolder. The extension expects this structure:',\r\n FS_TREE_PICK_HINT: '← select this folder',\r\n FS_TREE_READ_HINT: '← the extension will read here',\r\n FS_PERMISSION_NOTE: 'The permission is stored in the browser and will not be requested again.',\r\n ASSERTION_SECTION: '➕ Add assertion',\r\n ASSERT_SELECTOR_PH: 'selector, e.g.: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'expected value',\r\n ASSERT_ADD_BTN: '➕ Add',\r\n FILE_EDITOR_TITLE: '✏️ File editor',\r\n FILE_SAVED_TOAST: '✓ File saved',\r\n FILE_SAVE_ERROR_TOAST: 'Error saving the file',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Files',\r\n BTN_COMMANDS: 'Commands',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pause (Ctrl+P)',\r\n RESUME_TITLE: 'Resume (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSED',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Stop (Ctrl+R)',\r\n START_TITLE: 'Record (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_FR = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Paramètres',\r\n SHOW_ADVANCED_EDITOR: 'Éditeur avancé',\r\n DIALOG_SAVED_TESTS: 'Tests enregistrés',\r\n DIALOG_COMMANDS: 'Aperçu des commandes Cypress',\r\n DIALOG_SAVE: \"Enregistrer l'enregistrement ?\",\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Description du test',\r\n CANCEL: 'Annuler',\r\n ASK: 'Enregistrer le test ?',\r\n YES_CONTINUE: 'Oui, continuer',\r\n NO_DISCARD: 'Non, ignorer',\r\n DESC_PLACEHOLDER: 'Ex : Connexion réussie avec identifiants valides',\r\n TAGS_LABEL: 'Étiquettes (optionnel, pour filtrer ensuite) :',\r\n TAGS_PLACEHOLDER: 'smoke, login, régression…',\r\n ADD_TAG: '+ Ajouter',\r\n NO_TAGS: 'Sans étiquettes',\r\n SAVE_BTN: '💾 Enregistrer',\r\n SAVE_AND_EDIT: '📝 Enregistrer et éditer',\r\n REMOVE_TAG_TITLE: 'Retirer',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Sans étiquettes',\r\n SELECTED_SINGULAR: 'sélectionné',\r\n SELECTED_PLURAL: 'sélectionnés',\r\n DESCRIBE_PLACEHOLDER: 'Nom du describe (optionnel)',\r\n COPY_DESCRIBE: '🗂 Copier describe()',\r\n MULTI_SELECT: '🗂 Multi-sélection',\r\n CANCEL_SELECT: '✕ Annuler',\r\n SECTION_COMMANDS: 'Commandes',\r\n SECTION_INTERCEPTORS: 'Intercepteurs',\r\n COPY_CMDS_BTN: '📋 Copier les commandes',\r\n COPY_ICPS_BTN: '📋 Copier les intercepteurs',\r\n DEFAULT_DESCRIBE: 'Suite de tests',\r\n NO_TESTS: 'Aucun test enregistré',\r\n DELETE_TITLE: 'Supprimer',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Langue',\r\n LANG_FIELD: 'Interface',\r\n HTTP_SECTION: '⚡ HTTP Avancé',\r\n HTTP_TITLE: 'Validations du corps',\r\n HTTP_SUB: 'GET → réponse · POST/PUT → requête',\r\n SELECTOR_SECTION: '🎯 Stratégie de sélecteur',\r\n SELECTOR_LABEL: 'Attribut préféré pour cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (par défaut)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#élément)',\r\n SELECTOR_HINT: \"L'enregistreur cherchera d'abord cet attribut. Si absent, il essaiera les autres.\",\r\n FOLDER_SECTION: '📁 Dossier Cypress',\r\n FOLDER_CONNECTED: 'connecté —',\r\n FOLDER_NOT_SET: 'non configuré',\r\n FOLDER_CHANGE_BTN: '📁 Changer de dossier',\r\n FOLDER_SELECT_BTN: '📁 Sélectionner un dossier',\r\n FOLDER_REVOKE_BTN: \"✕ Révoquer l'accès\",\r\n DATA_SECTION: '💾 Données',\r\n DATA_DESC: 'Exportez tous vos tests en JSON ou importez une sauvegarde.',\r\n EXPORT_BTN: '⬆️ Exporter les tests',\r\n IMPORT_BTN: '⬇️ Importer les tests',\r\n FOLDER_UPDATED_TOAST: '✓ Dossier Cypress mis à jour',\r\n FOLDER_ERROR_TOAST: \"Erreur lors de l'accès au dossier\",\r\n IMPORT_SUCCESS: 'Données importées avec succès.',\r\n IMPORT_ERROR: \"Erreur lors de l'importation.\",\r\n JSON_INVALID: \"Le fichier n'est pas un JSON valide.\",\r\n JSON_BAD_FORMAT: \"Le fichier n'a pas le format attendu.\",\r\n SMART_SELECTOR_SECTION: '🔍 Sélecteur intelligent',\r\n SMART_SELECTOR_TITLE: 'Sélecteur intelligent',\r\n SMART_SELECTOR_SUB: 'Affiche un sélecteur lors du clic sur des éléments sans sélecteur valide.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Sélectionnez un élément du DOM',\r\n PREVIEW_LABEL: 'naviguer',\r\n CONFIRM_HINT: 'confirmer',\r\n CANCEL_HINT: 'annuler',\r\n QUALITY_EXCELLENT: 'Excellent — attribut de test présent (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Bon — id valide',\r\n QUALITY_ACCEPTABLE: 'Acceptable — classes CSS uniquement',\r\n QUALITY_POOR: 'Déconseillé — seulement le nom de balise ou style inline',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Intercepteurs',\r\n COPY_CMDS_BTN: '📋 Copier les commandes',\r\n SHOW_INTERCEPTORS: '▼ Voir les intercepteurs',\r\n HIDE_INTERCEPTORS: '▲ Masquer les intercepteurs',\r\n SECTION_COMMANDS: 'Commandes',\r\n NO_CMDS_YET: 'Aucune commande encore',\r\n NO_ICP_SHORT: 'Aucun intercepteur',\r\n COPY_ICP_BTN: '📋 Copier les intercepteurs',\r\n UP_TITLE: 'Monter',\r\n DOWN_TITLE: 'Descendre',\r\n DEL_TITLE: 'Supprimer',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: \"🔓 Réactiver l'accès\",\r\n PERMISSION_EXPIRED: '🔑 Autorisation expirée',\r\n PERMISSION_EXPIRED_HINT: \"Cliquez pour réactiver l'accès à votre dossier Cypress.\",\r\n NO_ACCESS: '🔒 Pas d\\'accès aux fichiers locaux',\r\n NO_ACCESS_HINT: \"Configurez l'accès dans ⚙️ Config.\",\r\n NO_FILES: 'Aucun fichier',\r\n SELECT_FILE: \"← Sélectionnez un fichier dans l'arborescence\",\r\n IT_LABEL: '🧪 it() à insérer :',\r\n COPY_IT_BTN: '📋 Copier it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() intercepteurs :',\r\n COPY_ICP_BTN: '📋 Copier les intercepteurs',\r\n INSERT_BTN: '💾 Insérer dans le fichier',\r\n EDIT_MANUAL_BTN: '✏️ Éditer manuellement',\r\n CLOSE_BTN: '✕ Fermer',\r\n NEW_FILE_BTN: '+ Nouveau fichier',\r\n REFRESH_BTN: '↻ Actualiser',\r\n NEW_FILE_PLACEHOLDER: 'nom-du-test',\r\n NEW_FILE_CONFIRM: 'Créer',\r\n NEW_FILE_CANCEL: 'Annuler',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Sans fichier',\r\n COPY_TITLE: \"Copier le contenu de l'éditeur\",\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copier',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: \"Aucun changement par rapport à l'original\",\r\n NO_CHANGES_SHORT: 'Aucun changement',\r\n LAUNCH_BTN: '▶ Lancer le test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Enregistrer',\r\n CLOSE_BTN: '✕ Fermer',\r\n BACK_TO_EDITOR: \"← Retour à l'éditeur\",\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Accès aux fichiers',\r\n FS_LATER_BTN: 'Pas maintenant',\r\n FS_SELECT_BTN: '📁 Sélectionner un dossier',\r\n FS_SUCCESS_TOAST: '✓ Dossier Cypress configuré',\r\n FS_ERROR_TOAST: \"Erreur lors de l'accès au dossier\",\r\n FS_INTRO_HTML: 'L\\'<strong style=\"color:#e6edf3\">éditeur avancé</strong> peut insérer vos tests directement dans les fichiers <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> de Cypress.',\r\n FS_STRUCTURE_HINT_HTML: 'Sélectionnez le dossier qui contient le sous-dossier <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code>. L\\'extension attend cette structure :',\r\n FS_TREE_PICK_HINT: '← sélectionnez ce dossier',\r\n FS_TREE_READ_HINT: '← l\\'extension lira ici',\r\n FS_PERMISSION_NOTE: 'L\\'autorisation est enregistrée dans le navigateur et ne sera plus demandée.',\r\n ASSERTION_SECTION: '➕ Ajouter une assertion',\r\n ASSERT_SELECTOR_PH: 'sélecteur, ex : [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'valeur attendue',\r\n ASSERT_ADD_BTN: '➕ Ajouter',\r\n FILE_EDITOR_TITLE: '✏️ Éditeur de fichier',\r\n FILE_SAVED_TOAST: '✓ Fichier enregistré',\r\n FILE_SAVE_ERROR_TOAST: \"Erreur lors de l'enregistrement\",\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Fichiers',\r\n BTN_COMMANDS: 'Commandes',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pause (Ctrl+P)',\r\n RESUME_TITLE: 'Reprendre (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSE',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Arrêter (Ctrl+R)',\r\n START_TITLE: 'Enregistrer (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_IT = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Impostazioni',\r\n SHOW_ADVANCED_EDITOR: 'Editor avanzato',\r\n DIALOG_SAVED_TESTS: 'Test salvati',\r\n DIALOG_COMMANDS: 'Anteprima comandi Cypress',\r\n DIALOG_SAVE: 'Salvare la registrazione?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Descrizione del test',\r\n CANCEL: 'Annulla',\r\n ASK: 'Salvare il test registrato?',\r\n YES_CONTINUE: 'Sì, continua',\r\n NO_DISCARD: 'No, annulla',\r\n DESC_PLACEHOLDER: 'Es: Login riuscito con credenziali valide',\r\n TAGS_LABEL: 'Etichette (opzionale, per filtrare dopo):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regressione…',\r\n ADD_TAG: '+ Aggiungi',\r\n NO_TAGS: 'Nessuna etichetta',\r\n SAVE_BTN: '💾 Salva',\r\n SAVE_AND_EDIT: '📝 Salva e modifica',\r\n REMOVE_TAG_TITLE: 'Rimuovi',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Nessuna etichetta',\r\n SELECTED_SINGULAR: 'selezionato',\r\n SELECTED_PLURAL: 'selezionati',\r\n DESCRIBE_PLACEHOLDER: 'Nome del describe (opzionale)',\r\n COPY_DESCRIBE: '🗂 Copia describe()',\r\n MULTI_SELECT: '🗂 Multi-selezione',\r\n CANCEL_SELECT: '✕ Annulla',\r\n SECTION_COMMANDS: 'Comandi',\r\n SECTION_INTERCEPTORS: 'Interceptor',\r\n COPY_CMDS_BTN: '📋 Copia comandi',\r\n COPY_ICPS_BTN: '📋 Copia interceptor',\r\n DEFAULT_DESCRIBE: 'Suite di test',\r\n NO_TESTS: 'Nessun test salvato',\r\n DELETE_TITLE: 'Elimina',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Lingua',\r\n LANG_FIELD: 'Interfaccia',\r\n HTTP_SECTION: '⚡ HTTP Avanzato',\r\n HTTP_TITLE: 'Validazioni del body',\r\n HTTP_SUB: 'GET → risposta · POST/PUT → richiesta',\r\n SELECTOR_SECTION: '🎯 Strategia selettore',\r\n SELECTOR_LABEL: 'Attributo preferito per cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (predefinito)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#elemento)',\r\n SELECTOR_HINT: \"Il registratore cercherà prima questo attributo. Se assente, proverà gli altri.\",\r\n FOLDER_SECTION: '📁 Cartella Cypress',\r\n FOLDER_CONNECTED: 'connesso —',\r\n FOLDER_NOT_SET: 'non configurato',\r\n FOLDER_CHANGE_BTN: '📁 Cambia cartella',\r\n FOLDER_SELECT_BTN: '📁 Seleziona cartella',\r\n FOLDER_REVOKE_BTN: '✕ Revoca accesso',\r\n DATA_SECTION: '💾 Dati',\r\n DATA_DESC: 'Esporta tutti i tuoi test in JSON o importa un backup.',\r\n EXPORT_BTN: '⬆️ Esporta test',\r\n IMPORT_BTN: '⬇️ Importa test',\r\n FOLDER_UPDATED_TOAST: '✓ Cartella Cypress aggiornata',\r\n FOLDER_ERROR_TOAST: \"Errore durante l'accesso alla cartella\",\r\n IMPORT_SUCCESS: 'Dati importati correttamente.',\r\n IMPORT_ERROR: \"Errore durante l'importazione.\",\r\n JSON_INVALID: 'Il file non è un JSON valido.',\r\n JSON_BAD_FORMAT: 'Il file non ha il formato previsto.',\r\n SMART_SELECTOR_SECTION: '🔍 Selettore intelligente',\r\n SMART_SELECTOR_TITLE: 'Selettore intelligente',\r\n SMART_SELECTOR_SUB: 'Mostra un selettore quando si fa clic su elementi senza selettore valido.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Seleziona un elemento DOM',\r\n PREVIEW_LABEL: 'navigare',\r\n CONFIRM_HINT: 'confermare',\r\n CANCEL_HINT: 'annullare',\r\n QUALITY_EXCELLENT: 'Eccellente — attributo di test presente (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Buono — id valido',\r\n QUALITY_ACCEPTABLE: 'Accettabile — solo classi CSS',\r\n QUALITY_POOR: 'Sconsigliato — solo tag o stile inline',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptor',\r\n COPY_CMDS_BTN: '📋 Copia comandi',\r\n SHOW_INTERCEPTORS: '▼ Vedi interceptor',\r\n HIDE_INTERCEPTORS: '▲ Nascondi interceptor',\r\n SECTION_COMMANDS: 'Comandi',\r\n NO_CMDS_YET: 'Ancora nessun comando',\r\n NO_ICP_SHORT: 'Nessun interceptor',\r\n COPY_ICP_BTN: '📋 Copia interceptor',\r\n UP_TITLE: 'Su',\r\n DOWN_TITLE: 'Giù',\r\n DEL_TITLE: 'Elimina',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Riattiva accesso',\r\n PERMISSION_EXPIRED: '🔑 Autorizzazione scaduta',\r\n PERMISSION_EXPIRED_HINT: \"Clicca per riattivare l'accesso alla cartella Cypress.\",\r\n NO_ACCESS: '🔒 Nessun accesso ai file locali',\r\n NO_ACCESS_HINT: \"Configura l'accesso in ⚙️ Config.\",\r\n NO_FILES: 'Nessun file',\r\n SELECT_FILE: \"← Seleziona un file dall'albero\",\r\n IT_LABEL: '🧪 it() da inserire:',\r\n COPY_IT_BTN: '📋 Copia it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() interceptor:',\r\n COPY_ICP_BTN: '📋 Copia interceptor',\r\n INSERT_BTN: '💾 Inserisci nel file',\r\n EDIT_MANUAL_BTN: '✏️ Modifica manualmente',\r\n CLOSE_BTN: '✕ Chiudi',\r\n NEW_FILE_BTN: '+ Nuovo file',\r\n REFRESH_BTN: '↻ Aggiorna',\r\n NEW_FILE_PLACEHOLDER: 'nome-del-test',\r\n NEW_FILE_CONFIRM: 'Crea',\r\n NEW_FILE_CANCEL: 'Annulla',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Nessun file',\r\n COPY_TITLE: \"Copia il contenuto dell'editor\",\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copia',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: \"Nessuna modifica rispetto all'originale\",\r\n NO_CHANGES_SHORT: 'Nessuna modifica',\r\n LAUNCH_BTN: '▶ Esegui test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Salva',\r\n CLOSE_BTN: '✕ Chiudi',\r\n BACK_TO_EDITOR: \"← Torna all'editor\",\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Accesso ai file',\r\n FS_LATER_BTN: 'Non ora',\r\n FS_SELECT_BTN: '📁 Seleziona cartella',\r\n FS_SUCCESS_TOAST: '✓ Cartella Cypress configurata',\r\n FS_ERROR_TOAST: \"Errore durante l'accesso alla cartella\",\r\n FS_INTRO_HTML: 'L\\'<strong style=\"color:#e6edf3\">editor avanzato</strong> può inserire i tuoi test direttamente nei file <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> di Cypress.',\r\n FS_STRUCTURE_HINT_HTML: 'Seleziona la cartella che contiene la sottocartella <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code>. L\\'estensione si aspetta questa struttura:',\r\n FS_TREE_PICK_HINT: '← seleziona questa cartella',\r\n FS_TREE_READ_HINT: '← l\\'estensione leggerà qui',\r\n FS_PERMISSION_NOTE: 'Il permesso viene salvato nel browser e non sarà richiesto di nuovo.',\r\n ASSERTION_SECTION: '➕ Aggiungi asserzione',\r\n ASSERT_SELECTOR_PH: 'selettore, es: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'valore atteso',\r\n ASSERT_ADD_BTN: '➕ Aggiungi',\r\n FILE_EDITOR_TITLE: '✏️ Editor di file',\r\n FILE_SAVED_TOAST: '✓ File salvato',\r\n FILE_SAVE_ERROR_TOAST: 'Errore durante il salvataggio',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'File',\r\n BTN_COMMANDS: 'Comandi',\r\n BTN_TESTS: 'Test',\r\n PAUSE_TITLE: 'Pausa (Ctrl+P)',\r\n RESUME_TITLE: 'Riprendi (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSA',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Ferma (Ctrl+R)',\r\n START_TITLE: 'Registra (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_DE = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Einstellungen',\r\n SHOW_ADVANCED_EDITOR: 'Erweiterter Editor',\r\n DIALOG_SAVED_TESTS: 'Gespeicherte Tests',\r\n DIALOG_COMMANDS: 'Cypress-Befehle Vorschau',\r\n DIALOG_SAVE: 'Aufzeichnung speichern?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Testbeschreibung',\r\n CANCEL: 'Abbrechen',\r\n ASK: 'Aufgezeichneten Test speichern?',\r\n YES_CONTINUE: 'Ja, weiter',\r\n NO_DISCARD: 'Nein, verwerfen',\r\n DESC_PLACEHOLDER: 'Z. B.: Erfolgreiche Anmeldung mit gültigen Zugangsdaten',\r\n TAGS_LABEL: 'Tags (optional, zum späteren Filtern):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regression…',\r\n ADD_TAG: '+ Hinzufügen',\r\n NO_TAGS: 'Keine Tags',\r\n SAVE_BTN: '💾 Speichern',\r\n SAVE_AND_EDIT: '📝 Speichern und bearbeiten',\r\n REMOVE_TAG_TITLE: 'Entfernen',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Keine Tags',\r\n SELECTED_SINGULAR: 'ausgewählt',\r\n SELECTED_PLURAL: 'ausgewählt',\r\n DESCRIBE_PLACEHOLDER: 'describe-Name (optional)',\r\n COPY_DESCRIBE: '🗂 describe() kopieren',\r\n MULTI_SELECT: '🗂 Mehrfachauswahl',\r\n CANCEL_SELECT: '✕ Abbrechen',\r\n SECTION_COMMANDS: 'Befehle',\r\n SECTION_INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Befehle kopieren',\r\n COPY_ICPS_BTN: '📋 Interceptors kopieren',\r\n DEFAULT_DESCRIBE: 'Test-Suite',\r\n NO_TESTS: 'Keine gespeicherten Tests',\r\n DELETE_TITLE: 'Löschen',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Sprache',\r\n LANG_FIELD: 'Oberfläche',\r\n HTTP_SECTION: '⚡ Erweitertes HTTP',\r\n HTTP_TITLE: 'Body-Validierungen',\r\n HTTP_SUB: 'GET → Antwort · POST/PUT → Anfrage',\r\n SELECTOR_SECTION: '🎯 Selector-Strategie',\r\n SELECTOR_LABEL: 'Bevorzugtes Attribut für cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (Standard)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#element)',\r\n SELECTOR_HINT: 'Der Recorder sucht zuerst nach diesem Attribut. Falls nicht gefunden, versucht er die anderen.',\r\n FOLDER_SECTION: '📁 Cypress-Ordner',\r\n FOLDER_CONNECTED: 'verbunden —',\r\n FOLDER_NOT_SET: 'nicht konfiguriert',\r\n FOLDER_CHANGE_BTN: '📁 Ordner wechseln',\r\n FOLDER_SELECT_BTN: '📁 Ordner auswählen',\r\n FOLDER_REVOKE_BTN: '✕ Zugriff widerrufen',\r\n DATA_SECTION: '💾 Daten',\r\n DATA_DESC: 'Exportieren Sie alle Tests als JSON oder importieren Sie ein Backup.',\r\n EXPORT_BTN: '⬆️ Tests exportieren',\r\n IMPORT_BTN: '⬇️ Tests importieren',\r\n FOLDER_UPDATED_TOAST: '✓ Cypress-Ordner aktualisiert',\r\n FOLDER_ERROR_TOAST: 'Fehler beim Zugriff auf den Ordner',\r\n IMPORT_SUCCESS: 'Daten erfolgreich importiert.',\r\n IMPORT_ERROR: 'Fehler beim Importieren.',\r\n JSON_INVALID: 'Die Datei ist kein gültiges JSON.',\r\n JSON_BAD_FORMAT: 'Die Datei hat nicht das erwartete Format.',\r\n SMART_SELECTOR_SECTION: '🔍 Intelligenter Selektor',\r\n SMART_SELECTOR_TITLE: 'Intelligenter Selektor',\r\n SMART_SELECTOR_SUB: 'Zeigt ein Auswahlfeld, wenn auf Elemente ohne gültigen Selektor geklickt wird.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'DOM-Element auswählen',\r\n PREVIEW_LABEL: 'navigieren',\r\n CONFIRM_HINT: 'bestätigen',\r\n CANCEL_HINT: 'abbrechen',\r\n QUALITY_EXCELLENT: 'Ausgezeichnet — Test-Attribut vorhanden (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Gut — gültige ID',\r\n QUALITY_ACCEPTABLE: 'Akzeptabel — nur CSS-Klassen',\r\n QUALITY_POOR: 'Nicht empfohlen — nur Tag oder Inline-Style',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Befehle kopieren',\r\n SHOW_INTERCEPTORS: '▼ Interceptors anzeigen',\r\n HIDE_INTERCEPTORS: '▲ Interceptors ausblenden',\r\n SECTION_COMMANDS: 'Befehle',\r\n NO_CMDS_YET: 'Noch keine Befehle',\r\n NO_ICP_SHORT: 'Keine Interceptors',\r\n COPY_ICP_BTN: '📋 Interceptors kopieren',\r\n UP_TITLE: 'Nach oben',\r\n DOWN_TITLE: 'Nach unten',\r\n DEL_TITLE: 'Löschen',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Zugriff reaktivieren',\r\n PERMISSION_EXPIRED: '🔑 Berechtigung abgelaufen',\r\n PERMISSION_EXPIRED_HINT: 'Klicken Sie, um den Zugriff auf Ihren Cypress-Ordner zu reaktivieren.',\r\n NO_ACCESS: '🔒 Kein Zugriff auf lokale Dateien',\r\n NO_ACCESS_HINT: 'Konfigurieren Sie den Zugriff unter ⚙️ Config.',\r\n NO_FILES: 'Keine Dateien',\r\n SELECT_FILE: '← Wählen Sie eine Datei aus dem Baum',\r\n IT_LABEL: '🧪 it() zum Einfügen:',\r\n COPY_IT_BTN: '📋 it() kopieren',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() Interceptors:',\r\n COPY_ICP_BTN: '📋 Interceptors kopieren',\r\n INSERT_BTN: '💾 In Datei einfügen',\r\n EDIT_MANUAL_BTN: '✏️ Manuell bearbeiten',\r\n CLOSE_BTN: '✕ Schließen',\r\n NEW_FILE_BTN: '+ Neue Datei',\r\n REFRESH_BTN: '↻ Aktualisieren',\r\n NEW_FILE_PLACEHOLDER: 'test-name',\r\n NEW_FILE_CONFIRM: 'Erstellen',\r\n NEW_FILE_CANCEL: 'Abbrechen',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Keine Datei',\r\n COPY_TITLE: 'Editor-Inhalt kopieren',\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Kopieren',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: 'Keine Änderungen gegenüber dem Original',\r\n NO_CHANGES_SHORT: 'Keine Änderungen',\r\n LAUNCH_BTN: '▶ Test starten',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Speichern',\r\n CLOSE_BTN: '✕ Schließen',\r\n BACK_TO_EDITOR: '← Zurück zum Editor',\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Dateizugriff',\r\n FS_LATER_BTN: 'Nicht jetzt',\r\n FS_SELECT_BTN: '📁 Ordner auswählen',\r\n FS_SUCCESS_TOAST: '✓ Cypress-Ordner konfiguriert',\r\n FS_ERROR_TOAST: 'Fehler beim Zugriff auf den Ordner',\r\n FS_INTRO_HTML: 'Der <strong style=\"color:#e6edf3\">erweiterte Editor</strong> kann Ihre Tests direkt in die Cypress-Dateien <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> einfügen.',\r\n FS_STRUCTURE_HINT_HTML: 'Wählen Sie den Ordner, der den Unterordner <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code> enthält. Die Erweiterung erwartet diese Struktur:',\r\n FS_TREE_PICK_HINT: '← diesen Ordner auswählen',\r\n FS_TREE_READ_HINT: '← die Erweiterung liest hier',\r\n FS_PERMISSION_NOTE: 'Die Berechtigung wird im Browser gespeichert und nicht erneut angefordert.',\r\n ASSERTION_SECTION: '➕ Assertion hinzufügen',\r\n ASSERT_SELECTOR_PH: 'Selektor, z. B.: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'erwarteter Wert',\r\n ASSERT_ADD_BTN: '➕ Hinzufügen',\r\n FILE_EDITOR_TITLE: '✏️ Datei-Editor',\r\n FILE_SAVED_TOAST: '✓ Datei gespeichert',\r\n FILE_SAVE_ERROR_TOAST: 'Fehler beim Speichern',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Dateien',\r\n BTN_COMMANDS: 'Befehle',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pausieren (Ctrl+P)',\r\n RESUME_TITLE: 'Fortsetzen (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSE',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Stopp (Ctrl+R)',\r\n START_TITLE: 'Aufzeichnen (Ctrl+R)',\r\n },\r\n};\r\n","import { type Lang, isLang } from '../models/lang.model';\r\nimport { I18N_ES } from '../i18n/es';\r\nimport { I18N_EN } from '../i18n/en';\r\nimport { I18N_FR } from '../i18n/fr';\r\nimport { I18N_IT } from '../i18n/it';\r\nimport { I18N_DE } from '../i18n/de';\r\n\r\ntype Translations = typeof I18N_ES;\r\n\r\nexport class TranslationService {\r\n private lang: Lang;\r\n\r\n private readonly translations: Record<Lang, Translations> = {\r\n es: I18N_ES,\r\n en: I18N_EN,\r\n fr: I18N_FR,\r\n it: I18N_IT,\r\n de: I18N_DE,\r\n };\r\n\r\n constructor() {\r\n this.lang = this.detectLang();\r\n }\r\n\r\n setLang(lang: Lang): void {\r\n this.lang = lang;\r\n }\r\n\r\n getLang(): Lang {\r\n return this.lang;\r\n }\r\n\r\n translate(key: string): string {\r\n const keys = key.split('.');\r\n let value: unknown = this.translations[this.lang];\r\n for (const k of keys) {\r\n value = (value as Record<string, unknown>)?.[k];\r\n if (value === undefined) return key;\r\n }\r\n return value as string;\r\n }\r\n\r\n detectLang(): Lang {\r\n const browserLang = navigator.language.split('-')[0];\r\n return isLang(browserLang) ? browserLang : 'es';\r\n }\r\n}\r\n\r\nexport const translationService = new TranslationService();\r\n","import { type Lang, isLang } from '../models/lang.model';\r\n\r\nexport class TransformationService {\r\n toLang(lang: string): Lang {\r\n return isLang(lang) ? lang : 'en';\r\n }\r\n\r\n generateItDescription(description: string, commands: string[]): string {\r\n const commandsBlock = commands.map((cmd) => ` ${cmd}`).join('\\n');\r\n return `it('${description}', () => {\\n${commandsBlock}\\n});`;\r\n }\r\n}\r\n\r\nexport const transformationService = new TransformationService();\r\n","export interface DirectoryNode {\r\n name: string;\r\n kind: 'directory';\r\n children: (DirectoryNode | FileNode)[];\r\n}\r\n\r\nexport interface FileNode {\r\n name: string;\r\n kind: 'file';\r\n}\r\n\r\nexport class AdvancedTestTransformationService {\r\n insertBeforeEach(content: string, interceptors: string, alertFn?: (msg: string) => void): string {\r\n const match = content.match(/(describe\\s*\\(.*?{)/s);\r\n if (!match) {\r\n alertFn?.('ADVANCED_EDITOR.NO_DESCRIBE');\r\n return '';\r\n }\r\n const insertPos = (match.index ?? 0) + match[0].length;\r\n const beforeEachBlock = `\\n beforeEach(() => {\\n${interceptors} })\\n`;\r\n return content.slice(0, insertPos) + beforeEachBlock + content.slice(insertPos);\r\n }\r\n\r\n insertItBlock(content: string, itBlock: string, alertFn?: (msg: string) => void): string {\r\n const idx = content.lastIndexOf('})');\r\n if (idx === -1) {\r\n alertFn?.('ADVANCED_EDITOR.NO_END');\r\n return '';\r\n }\r\n return content.slice(0, idx) + '\\n' + itBlock + '\\n' + content.slice(idx);\r\n }\r\n\r\n isFile(file: unknown): boolean {\r\n return !!file && (file as FileNode).kind === 'file';\r\n }\r\n\r\n async scanDirectory(dirHandle: FileSystemDirectoryHandle): Promise<DirectoryNode> {\r\n const result: DirectoryNode = { name: dirHandle.name, kind: 'directory', children: [] };\r\n for await (const entry of dirHandle.values()) {\r\n if (entry.kind === 'directory') {\r\n result.children.push(await this.scanDirectory(entry as FileSystemDirectoryHandle));\r\n } else {\r\n result.children.push({ name: entry.name, kind: 'file' });\r\n }\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nexport const advancedTestTransformationService = new AdvancedTestTransformationService();\r\n","export class Subject<T> {\r\n private _value: T;\r\n private listeners = new Set<(v: T) => void>();\r\n\r\n constructor(initialValue: T) {\r\n this._value = initialValue;\r\n }\r\n\r\n next(value: T): void {\r\n this._value = value;\r\n this.listeners.forEach((l) => l(value));\r\n }\r\n\r\n getValue(): T {\r\n return this._value;\r\n }\r\n\r\n subscribe(fn: (v: T) => void): () => void {\r\n this.listeners.add(fn);\r\n return () => this.listeners.delete(fn);\r\n }\r\n}\r\n","import { INPUT_TYPES } from '../models/input-types.model';\r\nimport { Subject } from '../utils/subject';\r\nimport { FORBIDDEN_ID_PREFIXES } from '../utils/selector-quality.utils';\r\n\r\nconst OWN_SELECTOR = '[data-cy=\"lib-e2e-cypress-for-dummys\"]';\r\n\r\nexport type SelectorStrategy = 'data-cy' | 'data-testid' | 'aria-label' | 'id';\r\n\r\nexport class RecordingService {\r\n private readonly commands$ = new Subject<string[]>([]);\r\n private readonly interceptors$ = new Subject<string[]>([]);\r\n private readonly isRecording$ = new Subject<boolean>(false);\r\n private readonly isPaused$ = new Subject<boolean>(false);\r\n private readonly selectorNotFound$ = new Subject<{ target: HTMLElement; action: 'click' } | null>(null);\r\n private readonly inputDebounceTimers = new Map<HTMLElement, ReturnType<typeof setTimeout>>();\r\n private readonly abort = new AbortController();\r\n\r\n selectorStrategy: SelectorStrategy = 'data-cy';\r\n\r\n // Stored originals for history patching cleanup\r\n private readonly origPushState = history.pushState.bind(history);\r\n private readonly origReplaceState = history.replaceState.bind(history);\r\n\r\n constructor() {\r\n this.listenToClicks();\r\n this.listenToInput();\r\n this.listenToSelect();\r\n this.listenToRouteChanges();\r\n }\r\n\r\n // ── Public API ────────────────────────────────────────────────────────────\r\n\r\n startRecording(): void {\r\n this.isPaused$.next(false);\r\n this.isRecording$.next(true);\r\n this.addCommand(`cy.viewport(1900, 1200)`);\r\n this.addCommand(`cy.visit('${window.location.pathname}')`);\r\n this.addCommand(`cy.get('[data-cy=\"lib-e2e-cypress-for-dummys\"]').invoke('hide');`);\r\n }\r\n\r\n stopRecording(): void {\r\n this.isPaused$.next(false);\r\n this.isRecording$.next(false);\r\n }\r\n\r\n toggleRecording(): void {\r\n if (this.isRecording$.getValue()) {\r\n this.stopRecording();\r\n } else {\r\n this.startRecording();\r\n }\r\n }\r\n\r\n pauseRecording(): void {\r\n if (!this.isRecording$.getValue()) return;\r\n this.isPaused$.next(true);\r\n }\r\n\r\n resumeRecording(): void {\r\n this.isPaused$.next(false);\r\n }\r\n\r\n togglePause(): void {\r\n if (this.isPaused$.getValue()) {\r\n this.resumeRecording();\r\n } else {\r\n this.pauseRecording();\r\n }\r\n }\r\n\r\n addCommand(cmd: string): void {\r\n if (!this.isRecording$.getValue() || this.isPaused$.getValue()) return;\r\n this.commands$.next([...this.commands$.getValue(), cmd]);\r\n }\r\n\r\n /** Appends a command regardless of recording/paused state (e.g. assertions added manually). */\r\n appendCommand(cmd: string): void {\r\n this.commands$.next([...this.commands$.getValue(), cmd]);\r\n }\r\n\r\n removeCommand(index: number): void {\r\n const cmds = this.commands$.getValue();\r\n if (index < 0 || index >= cmds.length) return;\r\n this.commands$.next([...cmds.slice(0, index), ...cmds.slice(index + 1)]);\r\n }\r\n\r\n moveCommand(from: number, to: number): void {\r\n const cmds = [...this.commands$.getValue()];\r\n if (from < 0 || to < 0 || from >= cmds.length || to >= cmds.length || from === to) return;\r\n const [item] = cmds.splice(from, 1);\r\n cmds.splice(to, 0, item);\r\n this.commands$.next(cmds);\r\n }\r\n\r\n removeInterceptor(index: number): void {\r\n const ints = this.interceptors$.getValue();\r\n if (index < 0 || index >= ints.length) return;\r\n this.interceptors$.next([...ints.slice(0, index), ...ints.slice(index + 1)]);\r\n }\r\n\r\n registerInterceptor(method: string, url: string, alias: string): void {\r\n if (this.isPaused$.getValue()) return;\r\n const command = `cy.intercept('${method}', '${this.urlToWildcard(url, method)}').as('${alias}')`;\r\n const current = this.interceptors$.getValue();\r\n if (!current.includes(command)) {\r\n this.interceptors$.next([...current, command]);\r\n }\r\n }\r\n\r\n clearCommands(): void {\r\n this.commands$.next([]);\r\n this.interceptors$.next([]);\r\n }\r\n\r\n clearInterceptors(): void {\r\n this.interceptors$.next([]);\r\n }\r\n\r\n getCommandsSnapshot(): string[] { return this.commands$.getValue(); }\r\n getInterceptorsSnapshot(): string[] { return this.interceptors$.getValue(); }\r\n getPausedSnapshot(): boolean { return this.isPaused$.getValue(); }\r\n\r\n onCommandsChange(fn: (cmds: string[]) => void): () => void {\r\n return this.commands$.subscribe(fn);\r\n }\r\n\r\n onInterceptorsChange(fn: (ints: string[]) => void): () => void {\r\n return this.interceptors$.subscribe(fn);\r\n }\r\n\r\n onRecordingChange(fn: (isRecording: boolean) => void): () => void {\r\n return this.isRecording$.subscribe(fn);\r\n }\r\n\r\n onPauseChange(fn: (isPaused: boolean) => void): () => void {\r\n return this.isPaused$.subscribe(fn);\r\n }\r\n\r\n onSelectorNotFound(fn: (target: HTMLElement, action: 'click') => void): () => void {\r\n return this.selectorNotFound$.subscribe((v) => {\r\n if (v) fn(v.target, v.action);\r\n });\r\n }\r\n\r\n destroy(): void {\r\n this.abort.abort();\r\n history.pushState = this.origPushState;\r\n history.replaceState = this.origReplaceState;\r\n this.inputDebounceTimers.forEach((t) => clearTimeout(t));\r\n this.inputDebounceTimers.clear();\r\n }\r\n\r\n // ── DOM listeners ─────────────────────────────────────────────────────────\r\n\r\n private listenToClicks(): void {\r\n document.addEventListener(\r\n 'click',\r\n (e: Event) => {\r\n if (!this.isRecording$.getValue()) return;\r\n const target = e.target as HTMLElement;\r\n if (!target || this.isOwnElement(target)) return;\r\n const tag = target.tagName?.toLowerCase();\r\n if (tag === 'body' || tag === 'html') return;\r\n this.handleClickEvent(target);\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n private listenToInput(): void {\r\n document.addEventListener(\r\n 'input',\r\n (e: Event) => {\r\n if (!this.isRecording$.getValue()) return;\r\n const target = e.target as HTMLInputElement | HTMLTextAreaElement;\r\n if (!target || this.isOwnElement(target)) return;\r\n this.handleInputEvent(target);\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n private listenToSelect(): void {\r\n document.addEventListener(\r\n 'change',\r\n (e: Event) => {\r\n if (!this.isRecording$.getValue()) return;\r\n const target = e.target as HTMLSelectElement;\r\n if (!target || this.isOwnElement(target)) return;\r\n if (target.tagName.toLowerCase() === 'select') {\r\n this.handleSelectEvent(target);\r\n }\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n private listenToRouteChanges(): void {\r\n let lastUrl = window.location.pathname + window.location.search + window.location.hash;\r\n\r\n const addUrlCommand = (newUrl: string): void => {\r\n if (!this.isRecording$.getValue()) return;\r\n if (newUrl === lastUrl) return;\r\n this.addCommand(`cy.url().should('include', '${newUrl}')`);\r\n lastUrl = newUrl;\r\n };\r\n\r\n const wrapMethod = (type: 'pushState' | 'replaceState'): void => {\r\n const orig = history[type].bind(history);\r\n history[type] = (data: unknown, unused: string, url?: string | URL | null) => {\r\n const result = orig(data, unused, url);\r\n let newUrl = window.location.pathname + window.location.search + window.location.hash;\r\n if (typeof url === 'string' && url.length > 0) {\r\n const a = document.createElement('a');\r\n a.href = url;\r\n newUrl = a.pathname + a.search + a.hash;\r\n } else if (url instanceof URL) {\r\n newUrl = url.pathname + url.search + url.hash;\r\n }\r\n addUrlCommand(newUrl);\r\n return result;\r\n };\r\n };\r\n\r\n wrapMethod('pushState');\r\n wrapMethod('replaceState');\r\n\r\n window.addEventListener(\r\n 'popstate',\r\n () => {\r\n const newUrl = window.location.pathname + window.location.search + window.location.hash;\r\n addUrlCommand(newUrl);\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n // ── Click helpers ─────────────────────────────────────────────────────────\r\n\r\n private handleClickEvent(target: HTMLElement): void {\r\n // Bubble up from non-interactive span/div inside button or mat-option\r\n if (!this.isInteractiveElement(target)) {\r\n const tag = target.tagName.toLowerCase();\r\n if (\r\n (tag === 'span' || tag === 'div') &&\r\n target.parentElement &&\r\n (target.parentElement.tagName.toLowerCase() === 'button' ||\r\n target.parentElement.tagName.toLowerCase() === 'mat-option') &&\r\n (target.parentElement.hasAttribute('data-cy') || target.parentElement.hasAttribute('id'))\r\n ) {\r\n target = target.parentElement;\r\n }\r\n const matSelect = target.closest('mat-select');\r\n if (matSelect) {\r\n const sel = this.getReliableSelector(matSelect as HTMLElement);\r\n if (sel) {\r\n this.addCommand(`cy.get('${sel}').click()`);\r\n } else {\r\n this.selectorNotFound$.next({ target: matSelect as HTMLElement, action: 'click' });\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const tag = target.tagName.toLowerCase();\r\n if (tag === 'input' || tag === 'textarea' || tag === 'select') {\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) this.selectorNotFound$.next({ target, action: 'click' });\r\n return;\r\n }\r\n\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) {\r\n this.selectorNotFound$.next({ target, action: 'click' });\r\n return;\r\n }\r\n\r\n const selector = this.getReliableSelector(container);\r\n if (selector === OWN_SELECTOR) return;\r\n\r\n if (tag === 'mat-option') {\r\n this.handleMatOptionClick(target, selector);\r\n return;\r\n }\r\n\r\n this.addGenericCommand({\r\n selector,\r\n action: (s) => `cy.get('${s}').click()`,\r\n });\r\n }\r\n\r\n private handleMatOptionClick(target: HTMLElement, selector: string | null): void {\r\n const matSelect = target.closest('mat-select');\r\n let dataCy: string | null = null;\r\n if (matSelect) dataCy = matSelect.closest('[data-cy]')?.getAttribute('data-cy') ?? null;\r\n if (!dataCy) dataCy = target.closest('[data-cy]')?.getAttribute('data-cy') ?? null;\r\n if (dataCy) {\r\n this.addCommand(`cy.get('[data-cy=\"${dataCy}\"]').click()`);\r\n return;\r\n }\r\n if (selector) {\r\n this.addCommand(`cy.get('${selector}').eq(0).click()`);\r\n } else {\r\n this.selectorNotFound$.next({ target, action: 'click' });\r\n }\r\n }\r\n\r\n // ── Input helpers ─────────────────────────────────────────────────────────\r\n\r\n private handleInputEvent(target: HTMLInputElement | HTMLTextAreaElement): void {\r\n const tag = target.tagName.toLowerCase();\r\n const isText = tag === 'textarea' || (tag === 'input' && (INPUT_TYPES as readonly string[]).includes(target.type));\r\n if (!isText) return;\r\n\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) return;\r\n\r\n if (this.inputDebounceTimers.has(target)) {\r\n clearTimeout(this.inputDebounceTimers.get(target));\r\n }\r\n this.inputDebounceTimers.set(\r\n target,\r\n setTimeout(() => {\r\n const selector = this.getReliableSelector(container);\r\n const value = target.value.replace(/'/g, \"\\\\'\");\r\n this.addGenericCommand({\r\n selector,\r\n action: (s) => `cy.get('${s}').clear().type('${value}')`,\r\n });\r\n this.inputDebounceTimers.delete(target);\r\n }, 1000)\r\n );\r\n }\r\n\r\n // ── Select helpers ────────────────────────────────────────────────────────\r\n\r\n private handleSelectEvent(target: HTMLSelectElement): void {\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) return;\r\n const selector = this.getReliableSelector(container);\r\n const value = target.value.replace(/'/g, \"\\\\'\");\r\n this.addGenericCommand({\r\n selector,\r\n action: (s) => `cy.get('${s}').select('${value}')`,\r\n });\r\n }\r\n\r\n // ── Shared helpers ────────────────────────────────────────────────────────\r\n\r\n private addGenericCommand(opts: {\r\n selector: string | null;\r\n action: (s: string) => string;\r\n }): void {\r\n if (!opts.selector || this.isOwnSelector(opts.selector)) return;\r\n this.addCommand(opts.action(opts.selector));\r\n }\r\n\r\n private getReliableSelector(el: HTMLElement): string | null {\r\n const strategy = this.selectorStrategy;\r\n const dataCy = el.getAttribute('data-cy');\r\n const dataTestid = el.getAttribute('data-testid');\r\n const ariaLabel = el.getAttribute('aria-label');\r\n const dataDotCy = el.getAttribute('data.cy');\r\n\r\n const rawId = el.id;\r\n const validId = rawId &&\r\n rawId.length < 25 &&\r\n /^[a-zA-Z][\\w-]*$/.test(rawId) &&\r\n !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) &&\r\n !/^\\d+$/.test(rawId) ? rawId : null;\r\n\r\n switch (strategy) {\r\n case 'data-testid':\r\n if (dataTestid) return `[data-testid=\"${dataTestid}\"]`;\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n return validId ? `#${validId}` : null;\r\n case 'aria-label':\r\n if (ariaLabel) return `[aria-label=\"${ariaLabel}\"]`;\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n return validId ? `#${validId}` : null;\r\n case 'id':\r\n if (validId) return `#${validId}`;\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n return dataTestid ? `[data-testid=\"${dataTestid}\"]` : null;\r\n default: // 'data-cy'\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n if (dataDotCy) return `[data.cy=\"${dataDotCy}\"]`;\r\n return validId ? `#${validId}` : null;\r\n }\r\n }\r\n\r\n private isInteractiveElement(target: EventTarget | null): boolean {\r\n if (!(target instanceof HTMLElement)) return false;\r\n const tag = target.tagName.toLowerCase();\r\n return ['select', 'option', 'input', 'textarea', 'button'].includes(tag);\r\n }\r\n\r\n private isOwnSelector(selector: string | null): boolean {\r\n return selector === OWN_SELECTOR;\r\n }\r\n\r\n private isOwnElement(target: HTMLElement): boolean {\r\n return !!target.closest('[data-cy=\"lib-e2e-cypress-for-dummys\"]');\r\n }\r\n\r\n private urlToWildcard(url: string, method: string): string {\r\n const u = new URL(url, 'http://localhost');\r\n if (method.toUpperCase() === 'GET' && u.search) {\r\n return `**${u.pathname}/**`;\r\n }\r\n return `**${u.pathname}`;\r\n }\r\n}\r\n","import { openDB, type IDBPDatabase } from 'idb';\r\nimport { DB_SCHEMA } from '../models/db-schema.model';\r\n\r\ninterface TestRecord { id: number; name: string; createdAt: number; tags?: string[]; }\r\ninterface CommandRecord { id: number; command: string; testId: number; createdAt: number; }\r\ninterface InterceptorRecord { id: number; interceptor: string; testId: number; createdAt: number; }\r\ninterface ConfigRecord { id: number; [key: string]: unknown; }\r\n\r\nexport interface TestWithDetails extends TestRecord {\r\n commands: string[];\r\n interceptors: string[];\r\n}\r\n\r\nexport interface TestDetail extends TestWithDetails {\r\n cypressCommands: string[];\r\n itBlock: string;\r\n interceptorsBlock: string;\r\n}\r\n\r\nexport class PersistenceService {\r\n private _db: Promise<IDBPDatabase> | null = null;\r\n\r\n // dbName is overridable so tests can use unique names for isolation.\r\n constructor(private readonly dbName: string = DB_SCHEMA.name) {}\r\n\r\n private getDB(): Promise<IDBPDatabase> {\r\n if (!this._db) {\r\n this._db = openDB(this.dbName, DB_SCHEMA.version, {\r\n upgrade(database) {\r\n for (const store of DB_SCHEMA.stores) {\r\n if (!database.objectStoreNames.contains(store.name)) {\r\n const os = database.createObjectStore(store.name, {\r\n keyPath: store.keyPath,\r\n autoIncrement: store.autoIncrement,\r\n });\r\n for (const index of store.indexes) {\r\n os.createIndex(index.name, index.keyPath, { unique: index.unique });\r\n }\r\n }\r\n }\r\n },\r\n });\r\n }\r\n return this._db;\r\n }\r\n\r\n // ── Tests ─────────────────────────────────────────────────────────────────\r\n\r\n async insertTest(name: string, commands: string[] = [], interceptors: string[] = [], tags: string[] = []): Promise<number> {\r\n const db = await this.getDB();\r\n const record: Omit<TestRecord, 'id'> = { name, createdAt: Date.now(), ...(tags.length ? { tags } : {}) };\r\n const id = await db.add('tests', record) as number;\r\n if (commands.length) await this.insertCommands(commands, id);\r\n if (interceptors.length) await this.insertInterceptors(interceptors, id);\r\n return id;\r\n }\r\n\r\n async getAllTests(): Promise<TestWithDetails[]> {\r\n const db = await this.getDB();\r\n const tests = await db.getAll('tests') as TestRecord[];\r\n return Promise.all(\r\n tests.map(async (test) => ({\r\n ...test,\r\n commands: await this.getCommandStrings(test.id),\r\n interceptors: await this.getInterceptorStrings(test.id),\r\n }))\r\n );\r\n }\r\n\r\n async getTestById(testId: number): Promise<TestDetail | null> {\r\n const db = await this.getDB();\r\n const record = await db.get('tests', testId) as TestRecord | undefined;\r\n if (!record) return null;\r\n\r\n const commands = await this.getCommandStrings(testId);\r\n const interceptors = await this.getInterceptorStrings(testId);\r\n const itBlock = `it('${record.name}', () => {\\n ${commands.join('\\n ')}\\n});`;\r\n const interceptorsBlock = interceptors.length\r\n ? ' // Auto-generated Cypress interceptors\\n' +\r\n interceptors.map((i) => ' ' + i).join('\\n') + '\\n'\r\n : '';\r\n\r\n return { ...record, commands, interceptors, cypressCommands: commands, itBlock, interceptorsBlock };\r\n }\r\n\r\n async deleteTest(id: number): Promise<void> {\r\n const db = await this.getDB();\r\n await db.delete('tests', id);\r\n await this.deleteCommandsByTestId(id);\r\n await this.deleteInterceptorsByTestId(id);\r\n }\r\n\r\n // ── Commands ──────────────────────────────────────────────────────────────\r\n\r\n async insertCommands(commands: string[], testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n await Promise.all(\r\n commands.map((command) => db.add('commands', { command, testId, createdAt: Date.now() }))\r\n );\r\n }\r\n\r\n async getCommandsByTestId(testId: number): Promise<CommandRecord[]> {\r\n const db = await this.getDB();\r\n return db.getAllFromIndex('commands', 'testId', testId) as Promise<CommandRecord[]>;\r\n }\r\n\r\n private async getCommandStrings(testId: number): Promise<string[]> {\r\n return (await this.getCommandsByTestId(testId)).map((r) => r.command).filter(Boolean);\r\n }\r\n\r\n private async deleteCommandsByTestId(testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n const rows = await this.getCommandsByTestId(testId);\r\n const tx = db.transaction('commands', 'readwrite');\r\n await Promise.all(rows.map((r) => tx.store.delete(r.id)));\r\n await tx.done;\r\n }\r\n\r\n // ── Interceptors ──────────────────────────────────────────────────────────\r\n\r\n async insertInterceptors(interceptors: string[], testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n await Promise.all(\r\n interceptors.map((interceptor) => db.add('interceptors', { interceptor, testId, createdAt: Date.now() }))\r\n );\r\n }\r\n\r\n async getInterceptorsByTestId(testId: number): Promise<InterceptorRecord[]> {\r\n const db = await this.getDB();\r\n return db.getAllFromIndex('interceptors', 'testId', testId) as Promise<InterceptorRecord[]>;\r\n }\r\n\r\n private async getInterceptorStrings(testId: number): Promise<string[]> {\r\n return (await this.getInterceptorsByTestId(testId)).map((r) => r.interceptor).filter(Boolean);\r\n }\r\n\r\n async deleteInterceptorsByTestId(testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n const rows = await this.getInterceptorsByTestId(testId);\r\n const tx = db.transaction('interceptors', 'readwrite');\r\n await Promise.all(rows.map((r) => tx.store.delete(r.id)));\r\n await tx.done;\r\n }\r\n\r\n // ── Configuration ─────────────────────────────────────────────────────────\r\n\r\n async setConfig(config: Record<string, unknown>): Promise<void> {\r\n const db = await this.getDB();\r\n const records = await db.getAll('configuration') as ConfigRecord[];\r\n const current = records[0] ?? {};\r\n const merged = { ...current, ...config };\r\n if ((current as ConfigRecord).id) {\r\n await db.put('configuration', merged);\r\n } else {\r\n await db.add('configuration', merged);\r\n }\r\n }\r\n\r\n async setConfigKey(key: string, value: unknown): Promise<void> {\r\n return this.setConfig({ [key]: value });\r\n }\r\n\r\n async getConfig(key: string): Promise<Record<string, unknown> | null> {\r\n const db = await this.getDB();\r\n const records = await db.getAll('configuration') as ConfigRecord[];\r\n if (!records.length) return null;\r\n const config = records[0];\r\n return Object.prototype.hasOwnProperty.call(config, key) ? { [key]: config[key] } : null;\r\n }\r\n\r\n async getGeneralConfig(): Promise<ConfigRecord | null> {\r\n const db = await this.getDB();\r\n const records = await db.getAll('configuration') as ConfigRecord[];\r\n return records[0] ?? null;\r\n }\r\n\r\n // ── Bulk operations ───────────────────────────────────────────────────────\r\n\r\n async clearAllData(): Promise<void> {\r\n const db = await this.getDB();\r\n await Promise.all([\r\n db.clear('tests'),\r\n db.clear('commands'),\r\n db.clear('interceptors'),\r\n ]);\r\n }\r\n\r\n async ingestFileData(tests: Record<string, unknown>[], interceptors: Record<string, unknown>[]): Promise<void> {\r\n await Promise.all([\r\n this.bulkInsertWithoutId('tests', tests),\r\n this.bulkInsertWithoutId('interceptors', interceptors),\r\n ]);\r\n }\r\n\r\n async requestDirectoryPermissions(): Promise<void> {\r\n if (!('showDirectoryPicker' in window)) {\r\n throw new Error('File System Access API not supported');\r\n }\r\n const dirHandle = await window.showDirectoryPicker();\r\n await this.setConfigKey('cypressDirectoryHandle', dirHandle);\r\n await this.setConfigKey('allowReadWriteFiles', 'true');\r\n }\r\n\r\n private async bulkInsertWithoutId(store: string, items: Record<string, unknown>[]): Promise<void> {\r\n if (!Array.isArray(items)) return;\r\n const db = await this.getDB();\r\n for (const item of items) {\r\n const { id: _id, ...rest } = item;\r\n await db.add(store, rest);\r\n }\r\n }\r\n}\r\n\r\nexport const persistenceService = new PersistenceService();\r\n","import { type RecordingService } from './recording.service';\r\n\r\nconst INTERCEPTED_METHODS = ['GET', 'POST', 'PUT'] as const;\r\ntype InterceptedMethod = (typeof INTERCEPTED_METHODS)[number];\r\n\r\nexport function generateAlias(method: string, url: string): string {\r\n try {\r\n const u = new URL(url, 'http://localhost');\r\n const path = u.pathname\r\n .replace(/[^a-zA-Z0-9]/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/(^-)|(-$)/g, '');\r\n return `${method.toLowerCase()}-${path}`;\r\n } catch {\r\n return `${method.toLowerCase()}-intercepted-request`;\r\n }\r\n}\r\n\r\nfunction buildValidations(base: string, obj: Record<string, unknown>): string {\r\n return Object.keys(obj)\r\n .filter((key) => key !== 'id' && key !== 'uid')\r\n .map((key) => `expect(${base}.${key}).to.equal(${JSON.stringify(obj[key])});`)\r\n .join('\\n');\r\n}\r\n\r\nfunction buildCyWaitCommand(\r\n method: string,\r\n alias: string,\r\n extendedHttp: boolean,\r\n requestBody: Record<string, unknown> | null,\r\n responseBody: Record<string, unknown> | null\r\n): string {\r\n if (extendedHttp && method === 'GET' && responseBody) {\r\n const validations = buildValidations('interception.response.body', responseBody);\r\n return `cy.wait('@${alias}').then((interception) => {\\n if (interception.response) {\\n${validations}\\n }\\n})`;\r\n }\r\n if (extendedHttp && (method === 'POST' || method === 'PUT') && requestBody) {\r\n const validations = buildValidations('interception.request.body', requestBody);\r\n return `cy.wait('@${alias}').then((interception) => {\\n${validations}\\n})`;\r\n }\r\n return `cy.wait('@${alias}').then((interception) => { })`;\r\n}\r\n\r\nfunction parseJsonObject(text: string): Record<string, unknown> | null {\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\r\n return parsed as Record<string, unknown>;\r\n }\r\n } catch {\r\n // Non-JSON or array — fall through\r\n }\r\n return null;\r\n}\r\n\r\nfunction parseRequestBody(init?: RequestInit): Record<string, unknown> | null {\r\n const body = init?.body;\r\n if (typeof body === 'string') return parseJsonObject(body);\r\n return null;\r\n}\r\n\r\nfunction resolveUrl(input: RequestInfo | URL): string {\r\n if (typeof input === 'string') return input;\r\n if (input instanceof URL) return input.href;\r\n return input.url;\r\n}\r\n\r\nfunction resolveMethod(input: RequestInfo | URL, init?: RequestInit): string {\r\n if (init?.method) return init.method.toUpperCase();\r\n if (input instanceof Request) return input.method.toUpperCase();\r\n return 'GET';\r\n}\r\n\r\nexport class HttpMonitor {\r\n private originalFetch: typeof window.fetch | null = null;\r\n private originalXHR: typeof XMLHttpRequest | null = null;\r\n\r\n constructor(private readonly recording: RecordingService) {}\r\n\r\n install(): void {\r\n this.installFetch();\r\n this.installXhr();\r\n }\r\n\r\n uninstall(): void {\r\n this.uninstallFetch();\r\n this.uninstallXhr();\r\n }\r\n\r\n isExtendedHttpEnabled(): boolean {\r\n return localStorage.getItem('extendedHttpCommands') === 'true';\r\n }\r\n\r\n private installFetch(): void {\r\n if (this.originalFetch) return;\r\n const originalFetch = window.fetch;\r\n this.originalFetch = originalFetch;\r\n\r\n window.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\r\n const response = await originalFetch(input, init);\r\n try {\r\n await this.handleFetchInterception(input, init, response.clone());\r\n } catch {\r\n // Never let monitoring errors break the actual request\r\n }\r\n return response;\r\n };\r\n }\r\n\r\n private uninstallFetch(): void {\r\n if (!this.originalFetch) return;\r\n window.fetch = this.originalFetch;\r\n this.originalFetch = null;\r\n }\r\n\r\n private installXhr(): void {\r\n if (this.originalXHR) return;\r\n this.originalXHR = window.XMLHttpRequest;\r\n const OrigXHR = this.originalXHR;\r\n const handleXhrInterception = this.handleXhrInterception.bind(this);\r\n\r\n window.XMLHttpRequest = class extends OrigXHR {\r\n private _xhrMethod = 'GET';\r\n private _xhrUrl = '';\r\n private _xhrRequestBody: Record<string, unknown> | null = null;\r\n\r\n override open(\r\n method: string,\r\n url: string | URL,\r\n async = true,\r\n user?: string | null,\r\n password?: string | null\r\n ): void {\r\n this._xhrMethod = method.toUpperCase();\r\n this._xhrUrl = url instanceof URL ? url.href : url;\r\n super.open(method, url as string, async, user, password);\r\n }\r\n\r\n override send(body?: Document | XMLHttpRequestBodyInit | null): void {\r\n if (typeof body === 'string') {\r\n this._xhrRequestBody = parseJsonObject(body);\r\n }\r\n this.addEventListener('load', () => {\r\n try {\r\n handleXhrInterception(\r\n this._xhrMethod,\r\n this._xhrUrl,\r\n this._xhrRequestBody,\r\n this.responseText\r\n );\r\n } catch {\r\n // Never let monitoring errors surface\r\n }\r\n });\r\n super.send(body);\r\n }\r\n } as unknown as typeof XMLHttpRequest;\r\n }\r\n\r\n private uninstallXhr(): void {\r\n if (!this.originalXHR) return;\r\n window.XMLHttpRequest = this.originalXHR;\r\n this.originalXHR = null;\r\n }\r\n\r\n private async handleFetchInterception(\r\n input: RequestInfo | URL,\r\n init: RequestInit | undefined,\r\n responseClone: Response\r\n ): Promise<void> {\r\n const method = resolveMethod(input, init);\r\n if (!(INTERCEPTED_METHODS as readonly string[]).includes(method)) return;\r\n\r\n const url = resolveUrl(input);\r\n const alias = generateAlias(method, url);\r\n\r\n this.recording.registerInterceptor(method, url, alias);\r\n\r\n const extendedHttp = this.isExtendedHttpEnabled();\r\n const requestBody = extendedHttp ? parseRequestBody(init) : null;\r\n let responseBody: Record<string, unknown> | null = null;\r\n if (extendedHttp) {\r\n try {\r\n responseBody = parseJsonObject(await responseClone.text());\r\n } catch {\r\n // Unreadable body — continue without validations\r\n }\r\n }\r\n\r\n const cmd = buildCyWaitCommand(method, alias, extendedHttp, requestBody, responseBody);\r\n this.recording.addCommand(cmd);\r\n }\r\n\r\n private handleXhrInterception(\r\n method: string,\r\n url: string,\r\n requestBody: Record<string, unknown> | null,\r\n responseText: string\r\n ): void {\r\n if (!(INTERCEPTED_METHODS as readonly string[]).includes(method as InterceptedMethod)) return;\r\n\r\n const alias = generateAlias(method, url);\r\n this.recording.registerInterceptor(method, url, alias);\r\n\r\n const extendedHttp = this.isExtendedHttpEnabled();\r\n const responseBody = extendedHttp ? parseJsonObject(responseText) : null;\r\n\r\n const cmd = buildCyWaitCommand(method, alias, extendedHttp, requestBody, responseBody);\r\n this.recording.addCommand(cmd);\r\n }\r\n}\r\n\r\n","export const SCROLLBAR_STYLES = `\r\n.swal2-popup::-webkit-scrollbar,\r\n.swal2-html-container::-webkit-scrollbar,\r\n.swal2-content::-webkit-scrollbar,\r\n.swal2-container::-webkit-scrollbar {\r\n width: 5px;\r\n height: 5px;\r\n background: transparent;\r\n}\r\n.swal2-popup::-webkit-scrollbar-thumb,\r\n.swal2-html-container::-webkit-scrollbar-thumb,\r\n.swal2-content::-webkit-scrollbar-thumb,\r\n.swal2-container::-webkit-scrollbar-thumb {\r\n background: #30363d;\r\n border-radius: 3px;\r\n}\r\n.swal2-popup::-webkit-scrollbar-thumb:hover,\r\n.swal2-html-container::-webkit-scrollbar-thumb:hover,\r\n.swal2-content::-webkit-scrollbar-thumb:hover {\r\n background: #484f58;\r\n}\r\n.swal2-popup::-webkit-scrollbar-track,\r\n.swal2-html-container::-webkit-scrollbar-track,\r\n.swal2-content::-webkit-scrollbar-track,\r\n.swal2-container::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n.swal2-popup, .swal2-html-container, .swal2-content, .swal2-container {\r\n scrollbar-width: thin;\r\n scrollbar-color: #30363d transparent;\r\n}\r\n`;\r\n\r\nexport const LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES = `\r\n.swal2-container, .swal2-popup {\r\n z-index: 99999 !important;\r\n}\r\n.swal2-container {\r\n padding: 0 !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n}\r\n.swal2-popup {\r\n background: #161b22 !important;\r\n color: #e6edf3 !important;\r\n border-radius: 12px !important;\r\n box-shadow: 0 24px 64px rgba(0,0,0,0.72), 0 0 0 1px #30363d !important;\r\n border: none !important;\r\n padding: 0 !important;\r\n min-width: 400px;\r\n max-width: 90vw;\r\n min-height: 200px;\r\n max-height: 90vh;\r\n}\r\n/* Override SweetAlert2 v11's display:grid on .swal2-popup.swal2-modal */\r\n.swal2-popup.swal2-modal {\r\n display: flex !important;\r\n flex-direction: column !important;\r\n align-items: stretch !important;\r\n overflow: hidden !important;\r\n}\r\n.swal2-header {\r\n flex-shrink: 0 !important;\r\n flex-grow: 0 !important;\r\n overflow: hidden !important;\r\n}\r\n.swal2-title {\r\n color: #e6edf3 !important;\r\n font-weight: 600 !important;\r\n font-size: 14px !important;\r\n background: #161b22;\r\n padding: 14px 48px 13px 18px !important;\r\n margin: 0 !important;\r\n border-bottom: 1px solid #21262d;\r\n text-align: left !important;\r\n letter-spacing: 0.1px;\r\n white-space: nowrap !important;\r\n overflow: hidden !important;\r\n text-overflow: ellipsis !important;\r\n}\r\n.swal2-close {\r\n position: absolute !important;\r\n top: 10px !important;\r\n right: 12px !important;\r\n color: #8b949e !important;\r\n font-size: 1.1rem !important;\r\n z-index: 1 !important;\r\n border-radius: 6px !important;\r\n width: 28px !important;\r\n height: 28px !important;\r\n line-height: 28px !important;\r\n transition: background 0.15s, color 0.15s !important;\r\n}\r\n.swal2-close:hover {\r\n background: #21262d !important;\r\n color: #e6edf3 !important;\r\n}\r\n/* In SweetAlert2 v11, .swal2-html-container is a direct child of .swal2-popup */\r\n.swal2-html-container {\r\n flex: 1 !important;\r\n min-height: 0 !important;\r\n background: #161b22;\r\n padding: 0 !important;\r\n margin: 0 !important;\r\n width: 100%;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n align-items: stretch;\r\n box-sizing: border-box;\r\n overflow: hidden !important;\r\n}\r\n/* The single wrapper div we inject inside each modal fills the container */\r\n.swal2-html-container > div {\r\n flex: 1 !important;\r\n min-height: 0 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n overflow: hidden !important;\r\n}\r\n.swal2-actions, .swal2-footer {\r\n flex-shrink: 0 !important;\r\n flex-grow: 0 !important;\r\n}\r\n`;\r\n\r\nexport function injectStyles(css: string, id: string): void {\r\n if (document.getElementById(id)) return;\r\n const style = document.createElement('style');\r\n style.id = id;\r\n style.innerHTML = css;\r\n document.head.appendChild(style);\r\n}\r\n","export function makeModalResizable(\r\n modal: HTMLElement,\r\n options?: { minWidth?: number; minHeight?: number }\r\n): () => void {\r\n if (!modal || modal.querySelector('.modal-resizer')) return () => { /* no-op */ };\r\n\r\n const rect = modal.getBoundingClientRect();\r\n modal.style.position = 'fixed';\r\n modal.style.top = `${rect.top}px`;\r\n modal.style.left = `${rect.left}px`;\r\n modal.style.width = `${rect.width}px`;\r\n modal.style.margin = '0';\r\n modal.style.resize = 'both';\r\n modal.style.overflow = 'hidden';\r\n modal.style.minWidth = (options?.minWidth ?? 320) + 'px';\r\n modal.style.minHeight = (options?.minHeight ?? 180) + 'px';\r\n\r\n const resizer = document.createElement('div');\r\n resizer.className = 'modal-resizer';\r\n resizer.style.position = 'absolute';\r\n resizer.style.width = '16px';\r\n resizer.style.height = '16px';\r\n resizer.style.right = '2px';\r\n resizer.style.bottom = '2px';\r\n resizer.style.cursor = 'nwse-resize';\r\n resizer.style.background = 'rgba(0,0,0,0.1)';\r\n resizer.style.zIndex = '10';\r\n modal.appendChild(resizer);\r\n\r\n let isResizing = false;\r\n let lastX = 0;\r\n let lastY = 0;\r\n\r\n const mouseMove = (e: MouseEvent): void => {\r\n if (!isResizing) return;\r\n const dx = e.clientX - lastX;\r\n const dy = e.clientY - lastY;\r\n lastX = e.clientX;\r\n lastY = e.clientY;\r\n const rect = modal.getBoundingClientRect();\r\n modal.style.width = rect.width + dx + 'px';\r\n modal.style.height = rect.height + dy + 'px';\r\n };\r\n\r\n const mouseUp = (): void => {\r\n isResizing = false;\r\n document.body.style.userSelect = '';\r\n };\r\n\r\n resizer.addEventListener('mousedown', (e) => {\r\n e.preventDefault();\r\n isResizing = true;\r\n lastX = e.clientX;\r\n lastY = e.clientY;\r\n document.body.style.userSelect = 'none';\r\n });\r\n\r\n window.addEventListener('mousemove', mouseMove);\r\n window.addEventListener('mouseup', mouseUp);\r\n\r\n return () => {\r\n window.removeEventListener('mousemove', mouseMove);\r\n window.removeEventListener('mouseup', mouseUp);\r\n if (resizer.parentNode) resizer.parentNode.removeChild(resizer);\r\n };\r\n}\r\n\r\nfunction applyDraggable(swal: HTMLElement, dragArea: HTMLElement): void {\r\n let isDragging = false;\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n\r\n dragArea.style.cursor = 'move';\r\n dragArea.onmousedown = (e: MouseEvent) => {\r\n isDragging = true;\r\n const rect = swal.getBoundingClientRect();\r\n offsetX = e.clientX - rect.left;\r\n offsetY = e.clientY - rect.top;\r\n document.onmousemove = (ev: MouseEvent) => {\r\n if (isDragging) {\r\n swal.style.position = 'fixed';\r\n swal.style.margin = '0';\r\n swal.style.left = `${ev.clientX - offsetX}px`;\r\n swal.style.top = `${ev.clientY - offsetY}px`;\r\n }\r\n };\r\n document.onmouseup = () => {\r\n isDragging = false;\r\n document.onmousemove = null;\r\n document.onmouseup = null;\r\n };\r\n };\r\n}\r\n\r\nfunction resolveDragArea(swal: HTMLElement): HTMLElement | null {\r\n return (swal.querySelector('.swal2-header') as HTMLElement | null)\r\n ?? (swal.querySelector('.swal2-title') as HTMLElement | null);\r\n}\r\n\r\nexport function makeSwalDraggable(): void {\r\n const popups = document.querySelectorAll('.swal2-popup');\r\n if (!popups.length) return;\r\n const swal = popups[popups.length - 1] as HTMLElement;\r\n const dragArea = resolveDragArea(swal);\r\n if (!dragArea) return;\r\n applyDraggable(swal, dragArea);\r\n}\r\n\r\nexport function makeSwalDraggableByContentId(contentId: string): void {\r\n const content = document.getElementById(contentId);\r\n if (!content) {\r\n makeSwalDraggable();\r\n return;\r\n }\r\n const swal = (content.closest('.swal2-popup') as HTMLElement | null)\r\n ?? (document.querySelector('.swal2-popup') as HTMLElement | null);\r\n if (!swal) return;\r\n const dragArea = resolveDragArea(swal);\r\n if (!dragArea) return;\r\n applyDraggable(swal, dragArea);\r\n}\r\n\r\nexport function setSwal2DataCyAttribute(dataCy = 'lib-e2e-cypress-for-dummys'): void {\r\n document.querySelector('.swal2-container')?.setAttribute('data-cy', dataCy);\r\n document.querySelector('.swal2-html-container')?.setAttribute('data-cy', dataCy);\r\n document.querySelector('.swal2-title')?.setAttribute('data-cy', dataCy);\r\n}\r\n","export function showToast(message: string, isSuccess = true): void {\r\n const toast = document.createElement('div');\r\n toast.textContent = message;\r\n toast.style.position = 'fixed';\r\n toast.style.top = '30px';\r\n toast.style.right = '30px';\r\n toast.style.padding = '16px 24px';\r\n toast.style.background = isSuccess ? '#4caf50' : '#f44336';\r\n toast.style.color = '#fff';\r\n toast.style.borderRadius = '8px';\r\n toast.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';\r\n toast.style.zIndex = '9999';\r\n toast.style.fontSize = '1rem';\r\n toast.style.fontWeight = 'bold';\r\n toast.style.pointerEvents = 'none';\r\n document.body.appendChild(toast);\r\n setTimeout(() => toast.remove(), 3000);\r\n}\r\n","export const TEST_PREVISUALIZER_STYLES = `\n :host { display: flex; flex-direction: column; flex: 1; min-height: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; overflow: hidden; }\n * { box-sizing: border-box; }\n .toolbar {\n display: flex; gap: 6px; padding: 10px 12px; flex-shrink: 0;\n background: #161b22; border-bottom: 1px solid #21262d;\n }\n button {\n padding: 5px 12px; border: none; border-radius: 6px; cursor: pointer;\n font-size: 11px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s; letter-spacing: 0.1px;\n }\n button:hover { background: #30363d; color: #e6edf3; }\n button.active { background: #2f81f7; color: #fff; }\n .section { padding: 10px 12px; flex-shrink: 0; }\n .section.section-cmds { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .section-title {\n font-size: 10px; font-weight: 600; color: #484f58; text-transform: uppercase;\n letter-spacing: 0.8px; margin-bottom: 7px; flex-shrink: 0;\n }\n .list {\n overflow-y: auto; background: #0d1117;\n border-radius: 8px; padding: 6px 8px;\n border: 1px solid #21262d;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .section-cmds .list { flex: 1; min-height: 0; }\n .list::-webkit-scrollbar { width: 4px; }\n .list::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .item {\n display: flex; align-items: flex-start; gap: 6px;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 11px;\n color: #c9d1d9; padding: 4px 8px; border-radius: 4px;\n word-break: break-all; line-height: 1.65;\n border-left: 2px solid transparent;\n transition: background 0.1s, border-color 0.1s;\n }\n .item:hover { background: #161b22; border-left-color: #2f81f7; }\n .cmd-text { flex: 1; }\n .item-actions {\n display: flex; gap: 3px; flex-shrink: 0;\n opacity: 0; transition: opacity 0.15s;\n }\n .item:hover .item-actions { opacity: 1; }\n .btn-step {\n width: 20px; height: 20px; border: none; border-radius: 3px; cursor: pointer;\n font-size: 12px; background: transparent; color: #484f58;\n transition: background 0.12s, color 0.12s;\n display: flex; align-items: center; justify-content: center;\n padding: 0; line-height: 1;\n }\n .btn-step:hover { background: #30363d; color: #e6edf3; }\n .btn-step-del:hover { background: rgba(248,81,73,0.15); color: #f85149; }\n .empty { color: #484f58; font-size: 12px; padding: 20px 8px; text-align: center; }\n`;\n","import { escHtml } from '../../utils/html.utils';\n\nexport function renderTestPrevisualizer(\n commands: string[],\n interceptors: string[],\n showInterceptors: boolean,\n editable: boolean,\n t: (key: string) => string,\n): string {\n const editControls = (idx: number, total: number) => editable ? `\n <span class=\"item-actions\">\n <button class=\"btn-step\" data-move-up=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.UP_TITLE')}\" ${idx === 0 ? 'disabled style=\"opacity:.3\"' : ''}>↑</button>\n <button class=\"btn-step\" data-move-dn=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.DOWN_TITLE')}\" ${idx === total - 1 ? 'disabled style=\"opacity:.3\"' : ''}>↓</button>\n <button class=\"btn-step btn-step-del\" data-del=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.DEL_TITLE')}\">✕</button>\n </span>` : '';\n\n const cmdItems = commands.length\n ? commands.map((c, i) => `\n <div class=\"item\">\n <span class=\"cmd-text\">${escHtml(c)}</span>\n ${editControls(i, commands.length)}\n </div>`).join('')\n : `<div class=\"empty\">${t('TEST_PREVISUALIZER.NO_CMDS_YET')}</div>`;\n\n const icpEditControls = (idx: number) => editable\n ? `<span class=\"item-actions\"><button class=\"btn-step btn-step-del\" data-del-icp=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.DEL_TITLE')}\">✕</button></span>`\n : '';\n\n const icpSection = showInterceptors\n ? `<div class=\"section\" data-section=\"interceptors\">\n <div class=\"section-title\">${t('TEST_PREVISUALIZER.INTERCEPTORS')}</div>\n <div class=\"list\">\n ${\n interceptors.length\n ? interceptors.map((ic, idx) => `\n <div class=\"item\">\n <span class=\"cmd-text\">${escHtml(ic)}</span>\n ${icpEditControls(idx)}\n </div>`).join('')\n : `<div class=\"empty\">${t('TEST_PREVISUALIZER.NO_ICP_SHORT')}</div>`\n }\n </div>\n <button style=\"margin-top:6px\" data-action=\"copy-icp\">${t('TEST_PREVISUALIZER.COPY_ICP_BTN')}</button>\n </div>`\n : '';\n\n return `\n <div class=\"toolbar\">\n <button data-action=\"copy\">${t('TEST_PREVISUALIZER.COPY_CMDS_BTN')}</button>\n <button data-action=\"toggle-icp\" class=\"${showInterceptors ? 'active' : ''}\">\n ${showInterceptors ? t('TEST_PREVISUALIZER.HIDE_INTERCEPTORS') : t('TEST_PREVISUALIZER.SHOW_INTERCEPTORS')} (${interceptors.length})\n </button>\n </div>\n <div class=\"section section-cmds\">\n <div class=\"section-title\">${t('TEST_PREVISUALIZER.SECTION_COMMANDS')} (${commands.length})</div>\n <div class=\"list\" data-ref=\"cmds\">${cmdItems}</div>\n </div>\n ${icpSection}`;\n}\n","import { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { TEST_PREVISUALIZER_STYLES } from './test-previsualizer.styles';\r\nimport { renderTestPrevisualizer } from './test-previsualizer.template';\r\n\r\nexport class TestPrevisualizerElement extends HTMLElement {\r\n private shadow: ShadowRoot\r\n private _commands: string[] = []\r\n private _interceptors: string[] = []\r\n private _showInterceptors = false\r\n editable = false\r\n translation: TranslationService = translationService\r\n\r\n constructor() {\r\n super()\r\n this.shadow = this.attachShadow({ mode: \"open\" })\r\n }\r\n\r\n connectedCallback(): void {\r\n this.render()\r\n }\r\n\r\n get commands(): string[] {\r\n return this._commands\r\n }\r\n set commands(v: string[]) {\r\n this._commands = v\r\n this.render()\r\n }\r\n\r\n get interceptors(): string[] {\r\n return this._interceptors\r\n }\r\n set interceptors(v: string[]) {\r\n this._interceptors = v\r\n this.render()\r\n }\r\n\r\n get showInterceptors(): boolean {\r\n return this._showInterceptors\r\n }\r\n\r\n toggleInterceptors(): void {\r\n this._showInterceptors = !this._showInterceptors\r\n this.render()\r\n }\r\n\r\n copyToClipboard(): void {\r\n const text = this._commands.join(\"\\n\")\r\n if (!text) return\r\n navigator.clipboard?.writeText(text)\r\n }\r\n\r\n copyInterceptorsToClipboard(): void {\r\n const text = this._interceptors.join(\"\\n\")\r\n if (!text) return\r\n navigator.clipboard?.writeText(text)\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key) }\r\n\r\n private dispatchDelete(index: number): void {\r\n this.dispatchEvent(new CustomEvent('deletecommand', { detail: index, bubbles: true, composed: true }))\r\n }\r\n\r\n private dispatchMove(from: number, to: number): void {\r\n this.dispatchEvent(new CustomEvent('movecommand', { detail: { from, to }, bubbles: true, composed: true }))\r\n }\r\n\r\n private dispatchDeleteInterceptor(index: number): void {\r\n this.dispatchEvent(new CustomEvent('deleteinterceptor', { detail: index, bubbles: true, composed: true }))\r\n }\r\n\r\n private render(): void {\r\n this.shadow.innerHTML = `<style>${TEST_PREVISUALIZER_STYLES}</style>${renderTestPrevisualizer(\r\n this._commands,\r\n this._interceptors,\r\n this._showInterceptors,\r\n this.editable,\r\n this.t.bind(this),\r\n )}`;\r\n\r\n const cmdsEl = this.shadow.querySelector<HTMLElement>('[data-ref=\"cmds\"]')\r\n if (cmdsEl) cmdsEl.scrollTop = cmdsEl.scrollHeight\r\n\r\n this.shadow.querySelector('[data-action=\"copy\"]')?.addEventListener(\"click\", () => this.copyToClipboard())\r\n this.shadow.querySelector('[data-action=\"toggle-icp\"]')?.addEventListener(\"click\", () => this.toggleInterceptors())\r\n this.shadow.querySelector('[data-action=\"copy-icp\"]')?.addEventListener(\"click\", () => this.copyInterceptorsToClipboard())\r\n\r\n if (this.editable) {\r\n this.shadow.querySelectorAll('[data-del]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n this.dispatchDelete(Number((btn as HTMLElement).dataset['del']))\r\n })\r\n })\r\n this.shadow.querySelectorAll('[data-move-up]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n const idx = Number((btn as HTMLElement).dataset['moveUp'])\r\n this.dispatchMove(idx, idx - 1)\r\n })\r\n })\r\n this.shadow.querySelectorAll('[data-move-dn]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n const idx = Number((btn as HTMLElement).dataset['moveDn'])\r\n this.dispatchMove(idx, idx + 1)\r\n })\r\n })\r\n this.shadow.querySelectorAll('[data-del-icp]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n this.dispatchDeleteInterceptor(Number((btn as HTMLElement).dataset['delIcp']))\r\n })\r\n })\r\n }\r\n }\r\n}\r\n\r\nif (!customElements.get(\"test-previsualizer\")) {\r\n customElements.define(\"test-previsualizer\", TestPrevisualizerElement)\r\n}\r\n","export const SAVE_TEST_STYLES = `\n :host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }\n * { box-sizing: border-box; }\n .container { padding: 24px 28px; text-align: center; }\n p { margin: 0 0 20px; font-size: 14px; color: #8b949e; line-height: 1.5; }\n .btn-row { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 16px; }\n button {\n padding: 7px 16px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; transition: filter 0.15s, transform 0.1s;\n letter-spacing: 0.1px;\n }\n button:hover { filter: brightness(1.1); }\n button:active { transform: scale(0.97); }\n .btn-primary { background: #2f81f7; color: #fff; }\n .btn-success { background: #3fb950; color: #fff; }\n .btn-danger { background: transparent; color: #f85149; border: 1px solid rgba(248,81,73,0.5); }\n .btn-danger:hover { background: rgba(248,81,73,0.08); filter: none; }\n input[type=\"text\"] {\n width: 100%; padding: 10px 14px; border: 1px solid #30363d;\n border-radius: 8px; background: #0d1117; color: #e6edf3;\n font-size: 14px; outline: none; margin-bottom: 4px;\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n input[type=\"text\"]:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.15); }\n input[type=\"text\"]::placeholder { color: #484f58; }\n .tag-label {\n font-size: 11px; color: #484f58; text-align: left; margin-bottom: 5px; display: block;\n }\n .tag-input-row { display: flex; gap: 6px; margin-bottom: 8px; }\n .tag-input-row input[type=\"text\"] {\n font-size: 12px; padding: 6px 10px; margin: 0;\n }\n .btn-tag-add {\n padding: 6px 12px; font-size: 12px; background: #21262d; color: #8b949e;\n border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n transition: background 0.15s, color 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-tag-add:hover { background: #30363d; color: #e6edf3; filter: none; }\n .chips { display: flex; flex-wrap: wrap; gap: 5px; min-height: 24px; text-align: left; }\n .chip {\n display: inline-flex; align-items: center; gap: 5px;\n background: rgba(47,129,247,0.15); color: #2f81f7;\n border: 1px solid rgba(47,129,247,0.3); border-radius: 20px;\n padding: 2px 10px 2px 10px; font-size: 11px; font-weight: 500;\n }\n .chip-del {\n cursor: pointer; color: #8b949e; font-size: 12px; line-height: 1;\n transition: color 0.12s; padding: 0; background: none; border: none;\n }\n .chip-del:hover { color: #f85149; filter: none; }\n`;\n","import { escHtml, escAttr } from '../../utils/html.utils';\n\nexport function renderSaveTestAsk(t: (key: string) => string): string {\n return `\n <div class=\"container\">\n <p>${t('SAVE_TEST.ASK')}</p>\n <div class=\"btn-row\">\n <button class=\"btn-primary\" id=\"btn-yes\">${t('SAVE_TEST.YES_CONTINUE')}</button>\n <button class=\"btn-danger\" id=\"btn-no\">${t('SAVE_TEST.NO_DISCARD')}</button>\n </div>\n </div>`;\n}\n\nexport function renderSaveTestDesc(description: string, tags: string[], t: (key: string) => string): string {\n const chipsHtml = tags.map((tag) =>\n `<span class=\"chip\">${escHtml(tag)}<button class=\"chip-del\" data-tag=\"${escAttr(tag)}\" title=\"${t('SAVE_TEST.REMOVE_TAG_TITLE')}\">✕</button></span>`\n ).join('');\n\n return `\n <div class=\"container\">\n <p>${t('SAVE_TEST.DESC_LABEL')} (<code>it()</code>):</p>\n <input id=\"desc-input\" type=\"text\" placeholder=\"${t('SAVE_TEST.DESC_PLACEHOLDER')}\"\n value=\"${escAttr(description)}\" autocomplete=\"off\" />\n <span class=\"tag-label\">${t('SAVE_TEST.TAGS_LABEL')}</span>\n <div class=\"tag-input-row\">\n <input id=\"tag-input\" type=\"text\" placeholder=\"${t('SAVE_TEST.TAGS_PLACEHOLDER')}\" autocomplete=\"off\" />\n <button class=\"btn-tag-add\" id=\"btn-add-tag\">${t('SAVE_TEST.ADD_TAG')}</button>\n </div>\n <div class=\"chips\" id=\"chips-container\">${chipsHtml || `<span style=\"color:#484f58;font-size:11px\">${t('SAVE_TEST.NO_TAGS')}</span>`}</div>\n <div class=\"btn-row\">\n <button class=\"btn-primary\" id=\"btn-confirm\">${t('SAVE_TEST.SAVE_BTN')}</button>\n <button class=\"btn-success\" id=\"btn-export\">${t('SAVE_TEST.SAVE_AND_EDIT')}</button>\n <button class=\"btn-danger\" id=\"btn-cancel\">${t('SAVE_TEST.CANCEL')}</button>\n </div>\n </div>`;\n}\n","import { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { SAVE_TEST_STYLES } from './save-test.styles';\r\nimport { renderSaveTestAsk, renderSaveTestDesc } from './save-test.template';\r\n\r\nexport class SaveTestElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private _step: 'ask' | 'desc' = 'ask';\r\n description = '';\r\n tags: string[] = [];\r\n translation: TranslationService = translationService;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void { this.render(); }\r\n\r\n get step(): 'ask' | 'desc' { return this._step; }\r\n\r\n askSave(): void { this._step = 'desc'; this.render(); }\r\n\r\n confirmSave(): void { this.dispatch('savetest', { description: this.description.trim(), tags: [...this.tags] }); }\r\n\r\n confirmSaveAndExport(): void { this.dispatch('saveandexport', { description: this.description.trim(), tags: [...this.tags] }); }\r\n\r\n cancel(): void { this.dispatch('savetest', { description: null, tags: [] }); }\r\n\r\n restartComponent(): void { this._step = 'ask'; this.description = ''; this.tags = []; this.render(); }\r\n\r\n addTag(tag: string): void {\r\n const t = tag.trim().replace(/[,;]/g, '');\r\n if (t && !this.tags.includes(t)) {\r\n this.tags = [...this.tags, t];\r\n this.render();\r\n }\r\n }\r\n\r\n removeTag(tag: string): void {\r\n this.tags = this.tags.filter((t) => t !== tag);\r\n this.render();\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private dispatch(type: string, detail: { description: string | null; tags: string[] }): void {\r\n this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));\r\n }\r\n\r\n private render(): void {\r\n if (this._step === 'ask') {\r\n this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestAsk(this.t.bind(this))}`;\r\n this.shadow.getElementById('btn-yes')?.addEventListener('click', () => this.askSave());\r\n this.shadow.getElementById('btn-no')?.addEventListener('click', () => this.cancel());\r\n } else {\r\n this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestDesc(this.description, this.tags, this.t.bind(this))}`;\r\n\r\n const descInput = this.shadow.getElementById('desc-input') as HTMLInputElement;\r\n const tagInput = this.shadow.getElementById('tag-input') as HTMLInputElement;\r\n\r\n descInput.addEventListener('input', () => { this.description = descInput.value; });\r\n\r\n const tryAddTag = () => {\r\n this.addTag(tagInput.value);\r\n tagInput.value = '';\r\n };\r\n this.shadow.getElementById('btn-add-tag')?.addEventListener('click', tryAddTag);\r\n tagInput.addEventListener('keydown', (e: KeyboardEvent) => {\r\n if (e.key === 'Enter' || e.key === ',') { e.preventDefault(); tryAddTag(); }\r\n });\r\n\r\n this.shadow.querySelectorAll<HTMLButtonElement>('.chip-del').forEach((btn) => {\r\n btn.addEventListener('click', () => this.removeTag(btn.dataset['tag'] ?? ''));\r\n });\r\n\r\n this.shadow.getElementById('btn-confirm')?.addEventListener('click', () => this.confirmSave());\r\n this.shadow.getElementById('btn-export')?.addEventListener('click', () => this.confirmSaveAndExport());\r\n this.shadow.getElementById('btn-cancel')?.addEventListener('click', () => this.cancel());\r\n setTimeout(() => descInput.focus(), 60);\r\n }\r\n }\r\n}\r\n\r\nif (!customElements.get('save-test')) {\r\n customElements.define('save-test', SaveTestElement);\r\n}\r\n","export const TEST_EDITOR_STYLES = `\n :host { display: flex; flex-direction: column; flex: 1; min-height: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; overflow: hidden; }\n * { box-sizing: border-box; }\n .toolbar {\n display: flex; align-items: center; gap: 6px; padding: 8px 10px; flex-shrink: 0;\n background: #161b22; border-bottom: 1px solid #21262d; flex-wrap: wrap;\n }\n .tag-filter { display: flex; gap: 5px; flex-wrap: wrap; flex: 1; }\n .tag-chip {\n padding: 2px 10px; border-radius: 20px; cursor: pointer; font-size: 11px; font-weight: 500;\n border: 1px solid #30363d; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s, border-color 0.12s;\n }\n .tag-chip:hover { background: #30363d; color: #e6edf3; }\n .tag-chip.active { background: rgba(47,129,247,0.2); color: #2f81f7; border-color: rgba(47,129,247,0.4); }\n .btn-select {\n padding: 4px 12px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 11px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-select:hover { background: #30363d; color: #e6edf3; }\n .btn-select.active { background: rgba(47,129,247,0.15); color: #2f81f7; border-color: rgba(47,129,247,0.3); }\n .describe-bar {\n display: flex; align-items: center; gap: 8px; padding: 8px 10px;\n background: rgba(47,129,247,0.06); border-bottom: 1px solid rgba(47,129,247,0.2);\n flex-wrap: wrap;\n }\n .describe-bar input {\n flex: 1; min-width: 150px; padding: 5px 10px; background: #0d1117;\n border: 1px solid #30363d; border-radius: 6px; color: #e6edf3;\n font-size: 12px; outline: none;\n }\n .describe-bar input:focus { border-color: #2f81f7; }\n .btn-gen-describe {\n padding: 5px 14px; border: 1px solid #2f81f7; border-radius: 6px; cursor: pointer;\n font-size: 11px; font-weight: 500; background: rgba(47,129,247,0.15); color: #2f81f7;\n transition: background 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-gen-describe:hover { background: rgba(47,129,247,0.25); }\n .selected-count { font-size: 11px; color: #8b949e; }\n .describe-bar { flex-shrink: 0; }\n .list { padding: 8px; flex: 1; min-height: 0; overflow-y: auto;\n scrollbar-width: thin; scrollbar-color: #30363d transparent; }\n .list::-webkit-scrollbar { width: 4px; }\n .list::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .empty { color: #484f58; text-align: center; padding: 32px; font-size: 13px; }\n .row {\n background: #0d1117; border-radius: 8px; margin-bottom: 6px;\n overflow: hidden; border: 1px solid #21262d;\n transition: border-color 0.15s;\n }\n .row:hover { border-color: #30363d; }\n .row.selected-row { border-color: rgba(47,129,247,0.5); }\n .row-header {\n display: flex; align-items: center; gap: 8px;\n padding: 10px 12px; cursor: pointer; user-select: none;\n }\n .row-header:hover { background: rgba(48,54,61,0.3); }\n .test-name { flex: 1; font-size: 13px; font-weight: 500; color: #e6edf3; }\n .test-date { font-size: 10.5px; color: #484f58; margin-right: 4px; }\n .test-tags { display: flex; gap: 4px; margin-right: 4px; }\n .test-tag {\n padding: 1px 7px; border-radius: 20px; font-size: 10px;\n background: rgba(47,129,247,0.1); color: #8b949e; border: 1px solid rgba(47,129,247,0.2);\n }\n .btn-icon {\n padding: 3px 8px; border: none; border-radius: 6px; cursor: pointer;\n font-size: 11px; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s;\n }\n .btn-icon:hover { background: #30363d; color: #e6edf3; }\n .btn-del:hover { background: rgba(248,81,73,0.15); color: #f85149; }\n input[type=\"checkbox\"] {\n width: 14px; height: 14px; accent-color: #2f81f7; cursor: pointer; flex-shrink: 0;\n }\n .row-body {\n background: #0d1117; padding: 10px 14px;\n border-top: 1px solid #21262d;\n }\n .section-title { font-size: 10px; color: #484f58; text-transform: uppercase;\n letter-spacing: 0.8px; margin-bottom: 6px; font-weight: 600; }\n .cmd-list { font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n font-size: 11px; color: #c9d1d9; line-height: 1.8; }\n .icp-list { font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n font-size: 11px; color: #3fb950; line-height: 1.8; margin-top: 10px; }\n .copy-row { display: flex; gap: 6px; margin-top: 10px; }\n`;\n","import { escHtml, escAttr } from '../../utils/html.utils';\nimport type { TestWithDetails } from '../../services/persistence.service';\n\nexport interface TestEditorState {\n tags: string[];\n visible: TestWithDetails[];\n selectedVisible: TestWithDetails[];\n activeTag: string | null;\n selectMode: boolean;\n selectedIds: Set<number>;\n describeName: string;\n expandedIndex: number | null;\n interceptorsByTest: Record<number, string[]>;\n}\n\nexport function renderTestEditor(state: TestEditorState, t: (key: string) => string): string {\n const { tags, visible, selectedVisible, activeTag, selectMode, selectedIds, describeName, expandedIndex, interceptorsByTest } = state;\n\n const tagFilterHtml = tags.length\n ? `<div class=\"tag-filter\">\n ${tags.map((tag) => `<button class=\"tag-chip${activeTag === tag ? ' active' : ''}\" data-filter-tag=\"${escAttr(tag)}\">${escHtml(tag)}</button>`).join('')}\n </div>`\n : `<div class=\"tag-filter\" style=\"color:#484f58;font-size:11px\">${t('TEST_EDITOR.NO_TAGS')}</div>`;\n\n const describeBarHtml = selectMode && selectedVisible.length > 0\n ? `<div class=\"describe-bar\">\n <span class=\"selected-count\">${selectedVisible.length} ${selectedVisible.length !== 1 ? t('TEST_EDITOR.SELECTED_PLURAL') : t('TEST_EDITOR.SELECTED_SINGULAR')}</span>\n <input id=\"describe-name\" type=\"text\" placeholder=\"${t('TEST_EDITOR.DESCRIBE_PLACEHOLDER')}\" value=\"${escAttr(describeName)}\" />\n <button class=\"btn-gen-describe\" id=\"btn-gen-describe\">${t('TEST_EDITOR.COPY_DESCRIBE')}</button>\n </div>`\n : '';\n\n const rows = visible.map((test, i) => {\n const expanded = expandedIndex === i;\n const date = new Date(test.createdAt).toLocaleString('es-ES', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });\n const icps = interceptorsByTest[test.id] ?? test.interceptors ?? [];\n const tagsHtml = (test.tags ?? []).length\n ? `<span class=\"test-tags\">${(test.tags ?? []).map((tag) => `<span class=\"test-tag\">${escHtml(tag)}</span>`).join('')}</span>`\n : '';\n const checkbox = selectMode\n ? `<input type=\"checkbox\" ${selectedIds.has(test.id) ? 'checked' : ''} data-select=\"${test.id}\" />`\n : '';\n const body = expanded ? `\n <div class=\"row-body\">\n <div class=\"section-title\">${t('TEST_EDITOR.SECTION_COMMANDS')} (${(test.commands ?? []).length})</div>\n <div class=\"cmd-list\">${(test.commands ?? []).map(escHtml).join('<br>')}</div>\n ${icps.length ? `<div class=\"icp-list\">\n <div class=\"section-title\" style=\"margin-top:8px\">${t('TEST_EDITOR.SECTION_INTERCEPTORS')}</div>\n ${icps.map(escHtml).join('<br>')}\n </div>` : ''}\n <div class=\"copy-row\">\n <button class=\"btn-icon\" data-action=\"copy-cmds\" data-idx=\"${i}\">${t('TEST_EDITOR.COPY_CMDS_BTN')}</button>\n ${icps.length ? `<button class=\"btn-icon\" data-action=\"copy-icps\" data-idx=\"${i}\">${t('TEST_EDITOR.COPY_ICPS_BTN')}</button>` : ''}\n </div>\n </div>` : '';\n return `\n <div class=\"row${selectedIds.has(test.id) ? ' selected-row' : ''}\">\n <div class=\"row-header\" data-action=\"expand\" data-idx=\"${i}\">\n ${checkbox}\n <span class=\"test-name\">${escHtml(test.name)}</span>\n ${tagsHtml}\n <span class=\"test-date\">${date}</span>\n <button class=\"btn-icon btn-del\" data-action=\"delete\" data-id=\"${test.id}\" title=\"${t('TEST_EDITOR.DELETE_TITLE')}\">🗑</button>\n </div>\n ${body}\n </div>`;\n }).join('');\n\n return `\n <div class=\"toolbar\">\n ${tagFilterHtml}\n <button class=\"btn-select${selectMode ? ' active' : ''}\" id=\"btn-select-mode\">\n ${selectMode ? t('TEST_EDITOR.CANCEL_SELECT') : t('TEST_EDITOR.MULTI_SELECT')}\n </button>\n </div>\n ${describeBarHtml}\n <div class=\"list\">\n ${visible.length ? rows : `<div class=\"empty\">${t('TEST_EDITOR.NO_TESTS')}</div>`}\n </div>`;\n}\n","import { PersistenceService } from '../../services/persistence.service';\r\nimport type { TestWithDetails } from '../../services/persistence.service';\r\nimport { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { TEST_EDITOR_STYLES } from './test-editor.styles';\r\nimport { renderTestEditor } from './test-editor.template';\r\n\r\nexport class TestEditorElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n persistence!: PersistenceService;\r\n translation: TranslationService = translationService;\r\n tests: TestWithDetails[] = [];\r\n expandedIndex: number | null = null;\r\n interceptorsByTest: Record<number, string[]> = {};\r\n activeTag: string | null = null;\r\n selectMode = false;\r\n selectedIds: Set<number> = new Set();\r\n describeName = '';\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.persistence) this.persistence = new PersistenceService();\r\n this.loadTests();\r\n }\r\n\r\n async loadTests(): Promise<void> {\r\n this.tests = await this.persistence.getAllTests();\r\n this.render();\r\n }\r\n\r\n async deleteTest(id: number): Promise<void> {\r\n await this.persistence.deleteTest(id);\r\n this.selectedIds.delete(id);\r\n await this.loadTests();\r\n }\r\n\r\n toggleExpand(index: number): void {\r\n this.expandedIndex = this.expandedIndex === index ? null : index;\r\n if (this.expandedIndex !== null) {\r\n const test = this.tests[this.expandedIndex];\r\n if (test?.id && !this.interceptorsByTest[test.id]) {\r\n this.interceptorsByTest[test.id] = Array.isArray(test.interceptors) ? test.interceptors : [];\r\n }\r\n }\r\n this.render();\r\n }\r\n\r\n hasInterceptors(testId: number): boolean {\r\n return Array.isArray(this.interceptorsByTest[testId]) && this.interceptorsByTest[testId].length > 0;\r\n }\r\n\r\n toggleSelectMode(): void {\r\n this.selectMode = !this.selectMode;\r\n if (!this.selectMode) this.selectedIds.clear();\r\n this.render();\r\n }\r\n\r\n toggleSelectTest(id: number): void {\r\n if (this.selectedIds.has(id)) this.selectedIds.delete(id);\r\n else this.selectedIds.add(id);\r\n this.render();\r\n }\r\n\r\n generateDescribe(): void {\r\n const selected = this.tests.filter((t) => this.selectedIds.has(t.id));\r\n if (!selected.length) return;\r\n\r\n const name = this.describeName.trim() || this.t('TEST_EDITOR.DEFAULT_DESCRIBE');\r\n\r\n const allInterceptors = [...new Set(\r\n selected.flatMap((t) => this.interceptorsByTest[t.id] ?? t.interceptors ?? [])\r\n )];\r\n\r\n const beforeEach = allInterceptors.length\r\n ? ` beforeEach(() => {\\n // Auto-generated Cypress interceptors\\n ${allInterceptors.join('\\n ')}\\n });\\n\\n`\r\n : '';\r\n\r\n const itBlocks = selected\r\n .map((t) => {\r\n const cmds = (t.commands ?? []).map((c) => ` ${c}`).join('\\n');\r\n return ` it('${(t.name ?? '').replace(/'/g, \"\\\\'\")}', () => {\\n${cmds}\\n });`;\r\n })\r\n .join('\\n\\n');\r\n\r\n const block = `describe('${name.replace(/'/g, \"\\\\'\")}', () => {\\n${beforeEach}${itBlocks}\\n});`;\r\n navigator.clipboard?.writeText(block);\r\n }\r\n\r\n copyToClipboard(text: string): void {\r\n navigator.clipboard?.writeText(text);\r\n }\r\n\r\n get allTags(): string[] {\r\n const tagSet = new Set<string>();\r\n this.tests.forEach((t) => (t.tags ?? []).forEach((tag) => tagSet.add(tag)));\r\n return [...tagSet].sort();\r\n }\r\n\r\n get visibleTests(): TestWithDetails[] {\r\n const tag = this.activeTag;\r\n if (!tag) return this.tests;\r\n return this.tests.filter((t) => (t.tags ?? []).includes(tag));\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private render(): void {\r\n const tags = this.allTags;\r\n const visible = this.visibleTests;\r\n const selectedVisible = visible.filter((t) => this.selectedIds.has(t.id));\r\n\r\n this.shadow.innerHTML = `<style>${TEST_EDITOR_STYLES}</style>${renderTestEditor({\r\n tags,\r\n visible,\r\n selectedVisible,\r\n activeTag: this.activeTag,\r\n selectMode: this.selectMode,\r\n selectedIds: this.selectedIds,\r\n describeName: this.describeName,\r\n expandedIndex: this.expandedIndex,\r\n interceptorsByTest: this.interceptorsByTest,\r\n }, this.t.bind(this))}`;\r\n\r\n this.shadow.getElementById('btn-select-mode')?.addEventListener('click', () => this.toggleSelectMode());\r\n\r\n this.shadow.querySelectorAll('[data-filter-tag]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n const tag = (el as HTMLElement).dataset['filterTag'] ?? '';\r\n if (!tag) return;\r\n this.activeTag = this.activeTag === tag ? null : tag;\r\n this.render();\r\n });\r\n });\r\n\r\n const descInput = this.shadow.getElementById('describe-name') as HTMLInputElement | null;\r\n if (descInput) {\r\n descInput.addEventListener('input', () => { this.describeName = descInput.value; });\r\n }\r\n this.shadow.getElementById('btn-gen-describe')?.addEventListener('click', () => {\r\n this.describeName = descInput?.value ?? this.describeName;\r\n this.generateDescribe();\r\n });\r\n\r\n this.shadow.querySelectorAll('[data-select]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n this.toggleSelectTest(Number((el as HTMLElement).dataset['select']));\r\n });\r\n });\r\n\r\n this.shadow.querySelectorAll('[data-action=\"expand\"]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n if (this.selectMode) {\r\n const row = visible[Number((el as HTMLElement).dataset['idx'])];\r\n if (row) this.toggleSelectTest(row.id);\r\n } else {\r\n this.toggleExpand(Number((el as HTMLElement).dataset['idx']));\r\n }\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-action=\"delete\"]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n this.deleteTest(Number((el as HTMLElement).dataset['id']));\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-action=\"copy-cmds\"]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n const idx = Number((el as HTMLElement).dataset['idx']);\r\n this.copyToClipboard((visible[idx]?.commands ?? []).join('\\n'));\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-action=\"copy-icps\"]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n const idx = Number((el as HTMLElement).dataset['idx']);\r\n const t = visible[idx];\r\n this.copyToClipboard((this.interceptorsByTest[t?.id] ?? []).join('\\n'));\r\n });\r\n });\r\n }\r\n}\r\n\r\nif (!customElements.get('test-editor')) {\r\n customElements.define('test-editor', TestEditorElement);\r\n}\r\n","export const CONFIGURATION_STYLES = `\n :host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }\n * { box-sizing: border-box; }\n\n /* ── Grid container ───────────────────────────────────── */\n .cfg-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n padding: 14px;\n }\n\n /* ── Cards ────────────────────────────────────────────── */\n .card {\n background: #161b22;\n border: 1px solid #21262d;\n border-radius: 10px;\n padding: 14px 16px;\n transition: border-color 0.15s;\n }\n .card:hover { border-color: #30363d; }\n .card-wide { grid-column: 1 / -1; }\n\n /* ── Card header ──────────────────────────────────────── */\n .card-hd {\n display: flex; align-items: center; gap: 7px;\n font-size: 10px; font-weight: 700; text-transform: uppercase;\n letter-spacing: 0.8px; color: #484f58; margin-bottom: 12px;\n }\n .card-hd-icon { font-size: 13px; }\n\n /* ── Language ─────────────────────────────────────────── */\n .field-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }\n .field-label { font-size: 12px; color: #8b949e; }\n select {\n background: #0d1117; color: #e6edf3; border: 1px solid #30363d;\n border-radius: 6px; padding: 6px 10px; font-size: 12px; outline: none;\n cursor: pointer; transition: border-color 0.15s; flex-shrink: 0;\n }\n select:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.12); }\n\n /* ── HTTP toggle ──────────────────────────────────────── */\n .check-row {\n display: flex; align-items: flex-start; gap: 10px;\n cursor: pointer; user-select: none;\n }\n input[type=\"checkbox\"] { width: 15px; height: 15px; margin-top: 2px; cursor: pointer; accent-color: #2f81f7; flex-shrink: 0; }\n .check-title { font-size: 12px; color: #c9d1d9; margin-bottom: 3px; }\n .check-sub { font-size: 10px; color: #484f58; line-height: 1.5; }\n\n /* ── Cypress folder ───────────────────────────────────── */\n .fs-layout { display: flex; gap: 12px; align-items: flex-start; }\n .fs-tree {\n flex-shrink: 0;\n margin: 0; padding: 8px 10px;\n background: #0d1117; border: 1px solid #21262d; border-radius: 6px;\n font-size: 10px; color: #c9d1d9; line-height: 1.8;\n font-family: 'Cascadia Code','Fira Code','Consolas',monospace;\n }\n .fs-right { display: flex; flex-direction: column; gap: 10px; flex: 1; }\n .fs-status {\n display: flex; align-items: center; gap: 8px;\n font-size: 12px; color: #8b949e;\n background: #0d1117; border: 1px solid #21262d; border-radius: 6px;\n padding: 8px 10px;\n }\n .fs-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }\n .fs-dot.on { background: #3fb950; box-shadow: 0 0 6px rgba(63,185,80,.5); }\n .fs-dot.off { background: #484f58; }\n .fs-folder { color: #e6edf3; font-family: 'Cascadia Code','Fira Code','Consolas',monospace; font-size: 11px; }\n\n /* ── Buttons ──────────────────────────────────────────── */\n .btn-row { display: flex; gap: 8px; flex-wrap: wrap; }\n button {\n padding: 7px 14px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s, border-color 0.15s;\n }\n button:hover { background: #30363d; color: #e6edf3; border-color: #484f58; }\n .btn-import {\n display: inline-block;\n padding: 7px 14px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s, border-color 0.15s;\n }\n .btn-import:hover { background: #30363d; color: #e6edf3; border-color: #484f58; }\n .btn-danger { border-color: rgba(248,81,73,.4); color: #f85149; background: transparent; }\n .btn-danger:hover { background: rgba(248,81,73,.08); border-color: #f85149; color: #f85149; }\n .file-input { display: none; }\n\n /* ── Data section desc ────────────────────────────────── */\n .data-desc { font-size: 11px; color: #484f58; margin-bottom: 10px; line-height: 1.5; }\n`;\n","export const LANGS = [\n { value: 'es', label: 'Español' },\n { value: 'en', label: 'English' },\n { value: 'fr', label: 'Français' },\n { value: 'it', label: 'Italiano' },\n { value: 'de', label: 'Deutsch' },\n];\n\nexport interface ConfigurationState {\n selectedLanguage: string;\n advancedHttpConfig: boolean;\n selectorStrategy: string;\n filesystemGranted: boolean;\n cypressFolderName: string | null;\n smartSelectorEnabled: boolean;\n}\n\nexport function renderConfiguration(state: ConfigurationState, t: (key: string) => string): string {\n const { selectedLanguage, advancedHttpConfig, selectorStrategy, filesystemGranted, cypressFolderName, smartSelectorEnabled } = state;\n\n const langOptions = LANGS.map(\n (l) => `<option value=\"${l.value}\" ${selectedLanguage === l.value ? 'selected' : ''}>${l.label}</option>`,\n ).join('');\n\n return `\n <div class=\"cfg-grid\">\n\n <!-- Language -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.LANG_SECTION')}</div>\n <div class=\"field-row\">\n <span class=\"field-label\">${t('CONFIG.LANG_FIELD')}</span>\n <select id=\"lang-select\">${langOptions}</select>\n </div>\n </div>\n\n <!-- HTTP Advanced -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.HTTP_SECTION')}</div>\n <label class=\"check-row\">\n <input type=\"checkbox\" id=\"http-toggle\" ${advancedHttpConfig ? 'checked' : ''} />\n <div>\n <div class=\"check-title\">${t('CONFIG.HTTP_TITLE')}</div>\n <div class=\"check-sub\">${t('CONFIG.HTTP_SUB')}</div>\n </div>\n </label>\n </div>\n\n <!-- Smart Selector -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.SMART_SELECTOR_SECTION')}</div>\n <label class=\"check-row\">\n <input type=\"checkbox\" id=\"smart-selector-toggle\" ${smartSelectorEnabled ? 'checked' : ''} />\n <div>\n <div class=\"check-title\">${t('CONFIG.SMART_SELECTOR_TITLE')}</div>\n <div class=\"check-sub\">${t('CONFIG.SMART_SELECTOR_SUB')}</div>\n </div>\n </label>\n </div>\n\n <!-- Selector Strategy -->\n <div class=\"card card-wide\">\n <div class=\"card-hd\">${t('CONFIG.SELECTOR_SECTION')}</div>\n <div class=\"field-row\">\n <span class=\"field-label\">${t('CONFIG.SELECTOR_LABEL')}</span>\n <select id=\"selector-strategy\">\n <option value=\"data-cy\" ${selectorStrategy === 'data-cy' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_DATACY')}</option>\n <option value=\"data-testid\" ${selectorStrategy === 'data-testid' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_TESTID')}</option>\n <option value=\"aria-label\" ${selectorStrategy === 'aria-label' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_ARIA')}</option>\n <option value=\"id\" ${selectorStrategy === 'id' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_ID')}</option>\n </select>\n </div>\n <div class=\"check-sub\" style=\"margin-top:8px\">${t('CONFIG.SELECTOR_HINT')}</div>\n </div>\n\n <!-- Cypress Folder -->\n <div class=\"card card-wide\">\n <div class=\"card-hd\">${t('CONFIG.FOLDER_SECTION')}</div>\n <div class=\"fs-layout\">\n <pre class=\"fs-tree\">cypress/ <span style=\"color:#484f58\">← selecciona</span>\n└── e2e/\n └── *.cy.ts</pre>\n <div class=\"fs-right\">\n <div class=\"fs-status\">\n <span class=\"fs-dot ${filesystemGranted ? 'on' : 'off'}\"></span>\n ${filesystemGranted && cypressFolderName\n ? `<span>${t('CONFIG.FOLDER_CONNECTED')}</span>&nbsp;<span class=\"fs-folder\">📁 ${cypressFolderName}</span>`\n : `<span>${t('CONFIG.FOLDER_NOT_SET')}</span>`}\n </div>\n <div class=\"btn-row\">\n <button id=\"btn-change-folder\">\n ${filesystemGranted ? t('CONFIG.FOLDER_CHANGE_BTN') : t('CONFIG.FOLDER_SELECT_BTN')}\n </button>\n ${filesystemGranted\n ? `<button id=\"btn-revoke\" class=\"btn-danger\">${t('CONFIG.FOLDER_REVOKE_BTN')}</button>`\n : ''}\n </div>\n </div>\n </div>\n </div>\n\n <!-- Data -->\n <div class=\"card card-wide\">\n <div class=\"card-hd\">${t('CONFIG.DATA_SECTION')}</div>\n <p class=\"data-desc\">${t('CONFIG.DATA_DESC')}</p>\n <div class=\"btn-row\">\n <button id=\"btn-export\">${t('CONFIG.EXPORT_BTN')}</button>\n <label style=\"cursor:pointer;margin:0\">\n <span class=\"btn-import\">${t('CONFIG.IMPORT_BTN')}</span>\n <input type=\"file\" class=\"file-input\" id=\"file-input\" accept=\".json\" />\n </label>\n </div>\n </div>\n\n </div>`;\n}\n","import { PersistenceService } from \"../../services/persistence.service\"\r\nimport { TranslationService } from \"../../services/translation.service\"\r\nimport type { Lang } from \"../../models/lang.model\"\r\nimport type { SelectorStrategy } from \"../../services/recording.service\"\r\nimport { showToast } from \"../../utils/toast.utils\"\r\nimport { CONFIGURATION_STYLES } from './configuration.styles';\r\nimport { renderConfiguration } from './configuration.template';\r\n\r\nexport class ConfigurationElement extends HTMLElement {\r\n private shadow: ShadowRoot\r\n persistence!: PersistenceService\r\n translation!: TranslationService\r\n selectedLanguage = \"es\"\r\n advancedHttpConfig = false\r\n selectorStrategy: SelectorStrategy = 'data-cy'\r\n smartSelectorEnabled = true\r\n private filesystemGranted = false\r\n private cypressFolderName: string | null = null\r\n\r\n constructor() {\r\n super()\r\n this.shadow = this.attachShadow({ mode: \"open\" })\r\n this.advancedHttpConfig = localStorage.getItem(\"extendedHttpCommands\") === \"true\"\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.persistence) this.persistence = new PersistenceService()\r\n if (!this.translation) this.translation = new TranslationService()\r\n this.loadConfig()\r\n this.render()\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private async loadConfig(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig()\r\n if (config?.['language']) {\r\n this.selectedLanguage = config['language'] as string\r\n this.translation.setLang(this.selectedLanguage as Lang)\r\n }\r\n this.advancedHttpConfig = localStorage.getItem(\"extendedHttpCommands\") === \"true\"\r\n this.selectorStrategy = (config?.['selectorStrategy'] as SelectorStrategy) ?? 'data-cy'\r\n this.smartSelectorEnabled = config?.['smartSelectorEnabled'] !== 'false'\r\n this.filesystemGranted = config?.['allowReadWriteFiles'] === 'true'\r\n const handle = config?.['cypressDirectoryHandle'] as FileSystemDirectoryHandle | undefined\r\n this.cypressFolderName = handle?.name ?? null\r\n this.render()\r\n }\r\n\r\n async onLanguageChange(lang: string): Promise<void> {\r\n this.selectedLanguage = lang\r\n this.translation.setLang(lang as Lang)\r\n await this.persistence.setConfig({ language: lang })\r\n this.render()\r\n }\r\n\r\n onAdvancedHttpConfigChange(checked: boolean): void {\r\n this.advancedHttpConfig = checked\r\n localStorage.setItem(\"extendedHttpCommands\", checked ? \"true\" : \"false\")\r\n this.persistence.setConfig({ extendedHttpCommands: checked ? \"true\" : \"false\" })\r\n this.render()\r\n }\r\n\r\n async onSmartSelectorChange(enabled: boolean): Promise<void> {\r\n this.smartSelectorEnabled = enabled\r\n await this.persistence.setConfig({ smartSelectorEnabled: enabled ? 'true' : 'false' })\r\n this.dispatchEvent(new CustomEvent('smartselectorchange', { detail: enabled, bubbles: true, composed: true }))\r\n this.render()\r\n }\r\n\r\n async onSelectorStrategyChange(strategy: SelectorStrategy): Promise<void> {\r\n this.selectorStrategy = strategy\r\n await this.persistence.setConfig({ selectorStrategy: strategy })\r\n this.dispatchEvent(new CustomEvent('selectorstrategychange', { detail: strategy, bubbles: true, composed: true }))\r\n this.render()\r\n }\r\n\r\n async changeFolder(): Promise<void> {\r\n try {\r\n await this.persistence.requestDirectoryPermissions()\r\n await this.loadConfig()\r\n showToast(this.t('CONFIG.FOLDER_UPDATED_TOAST'))\r\n } catch (e: unknown) {\r\n if ((e as DOMException)?.name !== 'AbortError') {\r\n showToast(this.t('CONFIG.FOLDER_ERROR_TOAST'), false)\r\n }\r\n }\r\n }\r\n\r\n async revokeAccess(): Promise<void> {\r\n await this.persistence.setConfig({ allowReadWriteFiles: 'false', cypressDirectoryHandle: null })\r\n this.filesystemGranted = false\r\n this.cypressFolderName = null\r\n this.render()\r\n }\r\n\r\n async exportAllData(): Promise<void> {\r\n const tests = await this.persistence.getAllTests()\r\n const blob = new Blob([JSON.stringify({ tests, interceptors: [] }, null, 2)], { type: \"application/json\" })\r\n const url = URL.createObjectURL(blob)\r\n const a = document.createElement(\"a\")\r\n a.href = url\r\n a.download = \"e2e-cypress-export.json\"\r\n a.click()\r\n URL.revokeObjectURL(url)\r\n }\r\n\r\n async importAllData(file: File): Promise<void> {\r\n const text = await file.text()\r\n let data: { tests: Record<string, unknown>[]; interceptors: Record<string, unknown>[] }\r\n try {\r\n data = JSON.parse(text)\r\n } catch {\r\n throw new Error(this.t('CONFIG.JSON_INVALID'))\r\n }\r\n if (!data || !Array.isArray(data.tests) || !Array.isArray(data.interceptors)) {\r\n throw new Error(this.t('CONFIG.JSON_BAD_FORMAT'))\r\n }\r\n await this.persistence.clearAllData()\r\n await this.persistence.ingestFileData(data.tests, data.interceptors)\r\n }\r\n\r\n private render(): void {\r\n this.shadow.innerHTML = `<style>${CONFIGURATION_STYLES}</style>${renderConfiguration({\r\n selectedLanguage: this.selectedLanguage,\r\n advancedHttpConfig: this.advancedHttpConfig,\r\n selectorStrategy: this.selectorStrategy,\r\n filesystemGranted: this.filesystemGranted,\r\n cypressFolderName: this.cypressFolderName,\r\n smartSelectorEnabled: this.smartSelectorEnabled,\r\n }, this.t.bind(this))}`;\r\n ;(this.shadow.getElementById(\"lang-select\") as HTMLSelectElement).addEventListener(\"change\", (e) =>\r\n this.onLanguageChange((e.target as HTMLSelectElement).value),\r\n )\r\n ;(this.shadow.getElementById(\"http-toggle\") as HTMLInputElement).addEventListener(\"change\", (e) =>\r\n this.onAdvancedHttpConfigChange((e.target as HTMLInputElement).checked),\r\n )\r\n ;(this.shadow.getElementById(\"smart-selector-toggle\") as HTMLInputElement).addEventListener(\"change\", (e) =>\r\n this.onSmartSelectorChange((e.target as HTMLInputElement).checked),\r\n )\r\n ;(this.shadow.getElementById(\"selector-strategy\") as HTMLSelectElement).addEventListener(\"change\", (e) =>\r\n this.onSelectorStrategyChange((e.target as HTMLSelectElement).value as SelectorStrategy),\r\n )\r\n\r\n this.shadow.getElementById(\"btn-change-folder\")?.addEventListener(\"click\", () => this.changeFolder())\r\n this.shadow.getElementById(\"btn-revoke\")?.addEventListener(\"click\", () => this.revokeAccess())\r\n this.shadow.getElementById(\"btn-export\")?.addEventListener(\"click\", () => this.exportAllData())\r\n ;(this.shadow.getElementById(\"file-input\") as HTMLInputElement).addEventListener(\"change\", async (e) => {\r\n const file = (e.target as HTMLInputElement).files?.[0]\r\n if (!file) return\r\n try {\r\n await this.importAllData(file)\r\n alert(this.t('CONFIG.IMPORT_SUCCESS'))\r\n } catch (err: unknown) {\r\n alert((err as Error).message ?? this.t('CONFIG.IMPORT_ERROR'))\r\n }\r\n const target = e.target as HTMLInputElement | null\r\n if (target) target.value = ''\r\n })\r\n }\r\n}\r\n\r\nif (!customElements.get(\"e2e-configuration\")) {\r\n customElements.define(\"e2e-configuration\", ConfigurationElement)\r\n}\r\n","export const ADVANCED_TEST_EDITOR_STYLES = `\n :host { display: flex; flex-direction: column; flex: 1; min-height: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; overflow: hidden; }\n * { box-sizing: border-box; }\n .layout { display: flex; flex: 1; min-height: 0; }\n .sidebar {\n border-right: none; display: flex; flex-direction: column;\n background: #0d1117; flex-shrink: 0; min-width: 140px; max-width: 500px;\n }\n .tree-scroll {\n flex: 1; overflow-y: auto; padding: 6px 4px;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .tree-scroll::-webkit-scrollbar { width: 4px; }\n .tree-scroll::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .resize-handle {\n width: 4px; background: #21262d; cursor: col-resize; flex-shrink: 0;\n transition: background 0.15s;\n }\n .resize-handle:hover, .resize-handle.dragging { background: #2f81f7; }\n .main { flex: 1; display: flex; flex-direction: column; overflow: hidden; background: #161b22; min-width: 0; }\n .no-perm {\n padding: 28px; color: #484f58; font-size: 13px; text-align: center;\n display: flex; flex-direction: column; align-items: center; gap: 12px; line-height: 1.6;\n }\n .tree-item {\n padding: 4px 6px; border-radius: 4px; cursor: pointer;\n font-size: 12px; color: #8b949e; white-space: nowrap;\n overflow: hidden; text-overflow: ellipsis;\n transition: background 0.12s, color 0.12s;\n display: flex; align-items: center; gap: 4px; user-select: none;\n }\n .tree-item:hover { background: #161b22; color: #c9d1d9; }\n .tree-item.selected { background: rgba(47,129,247,0.12); color: #2f81f7; }\n .tree-item.dir { color: #e3b341; font-weight: 600; }\n .tree-item.dir:hover { background: rgba(227,179,65,0.08); color: #f0c040; }\n .dir-arrow { font-size: 8px; color: #484f58; width: 10px; flex-shrink: 0; line-height: 1; }\n .tree-connector { display: block; width: 1px; background: #21262d; margin-left: 13px; height: 100%; }\n .content-area {\n flex: 1; padding: 12px 14px; overflow-y: auto;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .content-area::-webkit-scrollbar { width: 4px; }\n .content-area::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .file-name { font-size: 11px; color: #484f58; margin-bottom: 8px; font-family: monospace; }\n pre {\n background: #0d1117; padding: 12px; border-radius: 8px;\n font-size: 11px; color: #c9d1d9; overflow-x: auto;\n white-space: pre-wrap; word-break: break-all; margin: 0;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n line-height: 1.7; overflow-y: auto;\n border: 1px solid #21262d;\n }\n .footer {\n padding: 10px 14px; border-top: 1px solid #21262d;\n display: flex; gap: 8px; justify-content: flex-end; background: #161b22;\n }\n button {\n padding: 6px 16px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s;\n }\n button:hover { background: #30363d; color: #e6edf3; }\n button:disabled { opacity: 0.35; cursor: default; }\n .btn-save { background: #2f81f7; border-color: #2f81f7; color: #fff; }\n .btn-save:hover { background: #1f6feb; border-color: #1f6feb; color: #fff; }\n .btn-save:disabled { background: #21262d; border-color: #30363d; color: #8b949e; }\n .placeholder { color: #484f58; font-size: 13px; padding: 28px; text-align: center; }\n .block-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }\n .btn-copy {\n padding: 3px 10px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;\n font-size: 10px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-copy:hover { background: #30363d; color: #e6edf3; }\n .sidebar-toolbar {\n display: flex; gap: 4px; padding: 6px 6px 4px;\n border-bottom: 1px solid #21262d; flex-shrink: 0; background: #0d1117;\n }\n .btn-toolbar {\n flex: 1; padding: 4px 6px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;\n font-size: 10px; font-weight: 500; background: #161b22; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap; overflow: hidden;\n text-overflow: ellipsis;\n }\n .btn-toolbar:hover { background: #30363d; color: #e6edf3; }\n .btn-toolbar.btn-new { color: #3fb950; border-color: #238636; }\n .btn-toolbar.btn-new:hover { background: #238636; color: #fff; }\n .new-file-form {\n padding: 6px; border-bottom: 1px solid #21262d; display: flex; flex-direction: column; gap: 4px;\n }\n .new-file-form input {\n width: 100%; padding: 4px 7px; background: #0d1117; border: 1px solid #30363d;\n border-radius: 5px; color: #e6edf3; font-size: 11px; font-family: monospace;\n outline: none;\n }\n .new-file-form input:focus { border-color: #2f81f7; }\n .new-file-form .ext { font-size: 9px; color: #484f58; padding: 0 2px; }\n .new-file-actions { display: flex; gap: 4px; }\n .btn-confirm { flex: 1; padding: 3px 6px; border: 1px solid #238636; border-radius: 5px; cursor: pointer; font-size: 10px; font-weight: 500; background: #238636; color: #fff; transition: background 0.12s; }\n .btn-confirm:hover { background: #2ea043; }\n .btn-cancel-form { flex: 1; padding: 3px 6px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer; font-size: 10px; font-weight: 500; background: #21262d; color: #8b949e; transition: background 0.12s; }\n .btn-cancel-form:hover { background: #30363d; color: #e6edf3; }\n`;\n","import { escHtml, escAttr } from '../../utils/html.utils';\nimport type { DirectoryNode, FileNode } from '../../services/advanced-test.transformation.service';\n\nexport interface AdvancedEditorState {\n e2eTree: Array<DirectoryNode | FileNode>;\n selectedFile: unknown;\n selectedFileContent: string | null;\n testItBlock: string;\n interceptorsBlock: string;\n saveButtonEnabled: boolean;\n isCreatingFile: boolean;\n collapsedDirs: Set<string>;\n sidebarWidth: number;\n}\n\nexport function renderNoPermission(needsReauth: boolean, t: (key: string) => string): string {\n const reauthBtn = needsReauth\n ? `<button id=\"btn-reauth\"\n style=\"margin-top:14px;padding:7px 16px;border:none;border-radius:6px;cursor:pointer;\n font-size:12px;font-weight:500;background:#2f81f7;color:#fff\">\n ${t('ADVANCED_EDITOR.REAUTH_BTN')}\n </button>`\n : '';\n\n return `\n <div class=\"no-perm\">\n <div>${needsReauth ? t('ADVANCED_EDITOR.PERMISSION_EXPIRED') : t('ADVANCED_EDITOR.NO_ACCESS')}</div>\n <div style=\"font-size:11px\">${needsReauth\n ? t('ADVANCED_EDITOR.PERMISSION_EXPIRED_HINT')\n : t('ADVANCED_EDITOR.NO_ACCESS_HINT')}</div>\n ${reauthBtn}\n </div>`;\n}\n\nexport function renderAdvancedEditor(state: AdvancedEditorState, t: (key: string) => string): string {\n const { e2eTree, selectedFile, selectedFileContent, testItBlock, interceptorsBlock, saveButtonEnabled, isCreatingFile, collapsedDirs, sidebarWidth } = state;\n\n const treeHtml = e2eTree.length\n ? renderTree(e2eTree, selectedFile, collapsedDirs)\n : `<div class=\"tree-item\" style=\"color:#6c7a99\">${t('ADVANCED_EDITOR.NO_FILES')}</div>`;\n\n const contentHtml = selectedFileContent\n ? `<div class=\"file-name\">📄 ${escHtml((selectedFile as { name?: string } | null)?.name ?? '')}</div>\n <pre>${escHtml(selectedFileContent.slice(0, 4000))}${selectedFileContent.length > 4000 ? '\\n...' : ''}</pre>`\n : `<div class=\"placeholder\">${t('ADVANCED_EDITOR.SELECT_FILE')}</div>`;\n\n const itHtml = testItBlock\n ? `<div style=\"margin-top:10px\">\n <div class=\"file-name block-header\">\n <span>${t('ADVANCED_EDITOR.IT_LABEL')}</span>\n <button id=\"btn-copy-it\" class=\"btn-copy\">${t('ADVANCED_EDITOR.COPY_IT_BTN')}</button>\n </div>\n <pre style=\"max-height:120px;font-size:10.5px\">${escHtml(testItBlock.slice(0, 500))}</pre>\n </div>` : '';\n\n const interceptorsHtml = interceptorsBlock\n ? `<div style=\"margin-top:10px\">\n <div class=\"file-name block-header\">\n <span>${t('ADVANCED_EDITOR.BEFORE_EACH_LABEL')}</span>\n <button id=\"btn-copy-interceptors\" class=\"btn-copy\">${t('ADVANCED_EDITOR.COPY_ICP_BTN')}</button>\n </div>\n <pre style=\"max-height:120px;font-size:10.5px;color:#3fb950\">${escHtml(interceptorsBlock.slice(0, 500))}</pre>\n </div>` : '';\n\n const newFileForm = isCreatingFile\n ? `<div class=\"new-file-form\">\n <input id=\"input-new-file\" type=\"text\" placeholder=\"${escHtml(t('ADVANCED_EDITOR.NEW_FILE_PLACEHOLDER'))}\" autocomplete=\"off\" />\n <span class=\"ext\">.cy.ts</span>\n <div class=\"new-file-actions\">\n <button id=\"btn-new-file-confirm\" class=\"btn-confirm\">${t('ADVANCED_EDITOR.NEW_FILE_CONFIRM')}</button>\n <button id=\"btn-new-file-cancel\" class=\"btn-cancel-form\">${t('ADVANCED_EDITOR.NEW_FILE_CANCEL')}</button>\n </div>\n </div>`\n : '';\n\n const toolbar = `\n <div class=\"sidebar-toolbar\">\n <button id=\"btn-new-file\" class=\"btn-toolbar btn-new\">${t('ADVANCED_EDITOR.NEW_FILE_BTN')}</button>\n <button id=\"btn-refresh\" class=\"btn-toolbar\">${t('ADVANCED_EDITOR.REFRESH_BTN')}</button>\n </div>`;\n\n return `\n <div class=\"layout\">\n <div class=\"sidebar\" style=\"width:${sidebarWidth}px\">\n ${toolbar}\n ${newFileForm}\n <div class=\"tree-scroll\">${treeHtml}</div>\n </div>\n <div id=\"resize-handle\" class=\"resize-handle\"></div>\n <div class=\"main\">\n <div class=\"content-area\">${contentHtml}${itHtml}${interceptorsHtml}</div>\n <div class=\"footer\">\n <button id=\"btn-save\" class=\"btn-save\"\n ${!saveButtonEnabled || !testItBlock ? 'disabled' : ''}>\n ${t('ADVANCED_EDITOR.INSERT_BTN')}\n </button>\n <button id=\"btn-edit\" ${!saveButtonEnabled ? 'disabled' : ''}>\n ${t('ADVANCED_EDITOR.EDIT_MANUAL_BTN')}\n </button>\n <button id=\"btn-close\">${t('ADVANCED_EDITOR.CLOSE_BTN')}</button>\n </div>\n </div>\n </div>`;\n}\n\nexport function renderTree(\n nodes: Array<DirectoryNode | FileNode>,\n selected: unknown,\n collapsedDirs: Set<string>,\n indent = 0,\n parentPath = '',\n): string {\n return nodes.map((n) => {\n const currentPath = parentPath ? `${parentPath}/${n.name}` : n.name;\n const isFile = n.kind === 'file';\n const pad = `padding-left:${6 + indent * 14}px`;\n\n if (!isFile) {\n const dir = n as DirectoryNode;\n const hasChildren = (dir.children?.length ?? 0) > 0;\n const isCollapsed = collapsedDirs.has(currentPath);\n const arrow = hasChildren ? (isCollapsed ? '▶' : '▼') : '·';\n const dirHtml = `<div class=\"tree-item dir\" style=\"${pad}\" data-dir-path=\"${escAttr(currentPath)}\">\n <span class=\"dir-arrow\">${arrow}</span>📁 ${escHtml(n.name)}\n </div>`;\n if (!hasChildren || isCollapsed) return dirHtml;\n return dirHtml + renderTree(dir.children, selected, collapsedDirs, indent + 1, currentPath);\n }\n\n const isSel = (selected as { name?: string } | null)?.name === n.name;\n const cls = `tree-item${isSel ? ' selected' : ''}`;\n const data = JSON.stringify({ kind: n.kind, name: n.name }).replace(/\"/g, '&quot;');\n return `<div class=\"${cls}\" style=\"${pad}\" data-file=\"${data}\">📄 ${escHtml(n.name)}</div>`;\n }).join('');\n}\n\nexport async function findFileHandleRecursive(\n dir: FileSystemDirectoryHandle,\n name: string,\n): Promise<FileSystemFileHandle | null> {\n for await (const entry of dir.values()) {\n if (entry.kind === 'file' && entry.name === name) return entry as FileSystemFileHandle;\n if (entry.kind === 'directory') {\n const found = await findFileHandleRecursive(entry as FileSystemDirectoryHandle, name);\n if (found) return found;\n }\n }\n return null;\n}\n","import { PersistenceService } from '../../services/persistence.service';\r\nimport { TranslationService } from '../../services/translation.service';\r\nimport { AdvancedTestTransformationService } from '../../services/advanced-test.transformation.service';\r\nimport { ADVANCED_TEST_EDITOR_STYLES } from './advanced-test-editor.styles';\r\nimport { renderNoPermission, renderAdvancedEditor, findFileHandleRecursive } from './advanced-test-editor.template';\r\nimport type { DirectoryNode, FileNode } from '../../services/advanced-test.transformation.service';\r\n\r\nexport class AdvancedTestEditorElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private readonly transformationService = new AdvancedTestTransformationService();\r\n\r\n persistence!: PersistenceService;\r\n translation!: TranslationService;\r\n testId?: number;\r\n\r\n e2eTree: Array<DirectoryNode | FileNode> = [];\r\n selectedFile: unknown = null;\r\n saveButtonEnabled = false;\r\n selectedFileHandle: FileSystemFileHandle | null = null;\r\n selectedFileContent: string | null = null;\r\n testItBlock = '';\r\n interceptorsBlock = '';\r\n isPreviewMode = false;\r\n previewFileName: string | null = null;\r\n previewFileContent: string | null = null;\r\n isCreatingFile = false;\r\n collapsedDirs: Set<string> = new Set();\r\n sidebarWidth = 220;\r\n private hasPermission = false;\r\n private needsReauth = false;\r\n private _dirHandle: FileSystemDirectoryHandle | null = null;\r\n private _e2eHandle: FileSystemDirectoryHandle | null = null;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.persistence) this.persistence = new PersistenceService();\r\n if (!this.translation) this.translation = new TranslationService();\r\n this.init();\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private async init(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig();\r\n const allowed = config?.['allowReadWriteFiles'] === 'true';\r\n\r\n if (!allowed) {\r\n this.hasPermission = false;\r\n if (this.testId !== undefined) await this.loadCypressCommandsForTest(this.testId);\r\n this.render();\r\n return;\r\n }\r\n\r\n const handle = config?.['cypressDirectoryHandle'] as FileSystemDirectoryHandle | null;\r\n if (!handle) {\r\n this.hasPermission = false;\r\n if (this.testId !== undefined) await this.loadCypressCommandsForTest(this.testId);\r\n this.render();\r\n return;\r\n }\r\n\r\n // queryPermission does NOT require a user gesture\r\n const perm = await (handle as unknown as FileSystemHandleWithPermission).queryPermission({ mode: 'readwrite' });\r\n this._dirHandle = handle;\r\n this.hasPermission = perm === 'granted';\r\n this.needsReauth = perm === 'prompt';\r\n\r\n if (this.testId !== undefined) await this.loadCypressCommandsForTest(this.testId);\r\n if (this.hasPermission) await this.getFoldersData();\r\n this.render();\r\n }\r\n\r\n async getFoldersData(): Promise<void> {\r\n if (!this.hasPermission || !this._dirHandle) return;\r\n try {\r\n for await (const entry of this._dirHandle.values()) {\r\n if (entry.kind === 'directory' && entry.name === 'e2e') {\r\n this._e2eHandle = entry as FileSystemDirectoryHandle;\r\n const tree = await this.transformationService.scanDirectory(this._e2eHandle);\r\n this.e2eTree = tree.children ?? [];\r\n this.render();\r\n return;\r\n }\r\n }\r\n } catch { /* silently skip permission errors */ }\r\n }\r\n\r\n async createNewFile(rawName: string): Promise<void> {\r\n if (!this._e2eHandle) return;\r\n const name = rawName.trim().replace(/\\.cy\\.ts$/, '');\r\n if (!name) return;\r\n const fileName = `${name}.cy.ts`;\r\n const template = `describe('${name}', () => {\\n\\n it('should ', () => {\\n\\n });\\n\\n});\\n`;\r\n try {\r\n const fileHandle = await this._e2eHandle.getFileHandle(fileName, { create: true });\r\n const writable = await fileHandle.createWritable();\r\n await writable.write(template);\r\n await writable.close();\r\n } catch { /* silently ignore if file already exists or permission denied */ }\r\n this.isCreatingFile = false;\r\n await this.getFoldersData();\r\n }\r\n\r\n async refreshTree(): Promise<void> {\r\n await this.getFoldersData();\r\n }\r\n\r\n async saveCommandsToFile(): Promise<void> {\r\n if (!this.selectedFileHandle || !this.selectedFileContent || !this.testItBlock) return;\r\n let content = this.selectedFileContent;\r\n if (this.interceptorsBlock) {\r\n content = this.transformationService.insertBeforeEach(content, this.interceptorsBlock);\r\n }\r\n content = this.transformationService.insertItBlock(content, this.testItBlock);\r\n if (!content) return;\r\n const writable = await this.selectedFileHandle.createWritable();\r\n await writable.write(content);\r\n await writable.close();\r\n this.dispatchEvent(new CustomEvent('closemodal', { bubbles: true, composed: true }));\r\n }\r\n\r\n async onFileClick(file: unknown): Promise<void> {\r\n if (!this.transformationService.isFile(file)) return;\r\n this.selectedFile = file;\r\n this.saveButtonEnabled = true;\r\n\r\n if (!this._dirHandle) return;\r\n const handle = await findFileHandleRecursive(this._dirHandle, (file as { name: string }).name);\r\n if (!handle) return;\r\n this.selectedFileHandle = handle;\r\n const fileObj = await handle.getFile();\r\n this.selectedFileContent = await fileObj.text();\r\n this.render();\r\n }\r\n\r\n markFileAsSelected(file: unknown): void {\r\n this.selectedFile = file;\r\n }\r\n\r\n async loadCypressCommandsForTest(testId: number): Promise<void> {\r\n const test = await this.persistence.getTestById(testId);\r\n if (test) {\r\n this.testItBlock = test.itBlock ?? '';\r\n this.interceptorsBlock = test.interceptorsBlock ?? '';\r\n } else {\r\n this.testItBlock = '';\r\n this.interceptorsBlock = '';\r\n }\r\n this.render();\r\n }\r\n\r\n copyToClipboard(text: string): void {\r\n navigator.clipboard?.writeText(text);\r\n }\r\n\r\n openEditManually(): void {\r\n if (!this.selectedFileHandle || !this.selectedFileContent) return;\r\n this.dispatchEvent(new CustomEvent('openfileeditor', {\r\n detail: {\r\n handle: this.selectedFileHandle,\r\n content: this.selectedFileContent,\r\n fileName: (this.selectedFile as { name?: string } | null)?.name ?? '',\r\n testId: this.testId,\r\n itBlock: this.testItBlock,\r\n interceptorsBlock: this.interceptorsBlock,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n }\r\n\r\n toggleDir(path: string): void {\r\n if (this.collapsedDirs.has(path)) {\r\n this.collapsedDirs.delete(path);\r\n } else {\r\n this.collapsedDirs.add(path);\r\n }\r\n this.render();\r\n }\r\n\r\n private setupResizeHandle(): void {\r\n const handle = this.shadow.getElementById('resize-handle');\r\n const sidebar = this.shadow.querySelector('.sidebar') as HTMLElement | null;\r\n if (!handle || !sidebar) return;\r\n\r\n let startX = 0;\r\n let startWidth = 0;\r\n\r\n const onMouseMove = (e: MouseEvent) => {\r\n const delta = e.clientX - startX;\r\n const newWidth = Math.max(140, Math.min(500, startWidth + delta));\r\n this.sidebarWidth = newWidth;\r\n sidebar.style.width = `${newWidth}px`;\r\n };\r\n\r\n const onMouseUp = () => {\r\n document.removeEventListener('mousemove', onMouseMove);\r\n document.removeEventListener('mouseup', onMouseUp);\r\n document.body.style.cursor = '';\r\n document.body.style.userSelect = '';\r\n handle.classList.remove('dragging');\r\n };\r\n\r\n handle.addEventListener('mousedown', (e: MouseEvent) => {\r\n startX = e.clientX;\r\n startWidth = sidebar.offsetWidth;\r\n document.addEventListener('mousemove', onMouseMove);\r\n document.addEventListener('mouseup', onMouseUp);\r\n document.body.style.cursor = 'col-resize';\r\n document.body.style.userSelect = 'none';\r\n handle.classList.add('dragging');\r\n e.preventDefault();\r\n });\r\n }\r\n\r\n closePreview(): void {\r\n this.isPreviewMode = false;\r\n this.previewFileName = null;\r\n this.previewFileContent = null;\r\n if (this.testId !== undefined) {\r\n this.dispatchEvent(new CustomEvent('closemodal', { bubbles: true, composed: true }));\r\n }\r\n this.render();\r\n }\r\n\r\n private render(): void {\r\n if (!this.hasPermission) {\r\n this.shadow.innerHTML = `<style>${ADVANCED_TEST_EDITOR_STYLES}</style>${renderNoPermission(this.needsReauth, this.t.bind(this))}`;\r\n\r\n this.shadow.getElementById('btn-reauth')?.addEventListener('click', async () => {\r\n if (!this._dirHandle) return;\r\n const perm = await (this._dirHandle as unknown as FileSystemHandleWithPermission).requestPermission({ mode: 'readwrite' });\r\n if (perm === 'granted') {\r\n this.hasPermission = true;\r\n this.needsReauth = false;\r\n await this.getFoldersData();\r\n this.render();\r\n }\r\n });\r\n return;\r\n }\r\n\r\n this.shadow.innerHTML = `<style>${ADVANCED_TEST_EDITOR_STYLES}</style>${renderAdvancedEditor({\r\n e2eTree: this.e2eTree,\r\n selectedFile: this.selectedFile,\r\n selectedFileContent: this.selectedFileContent,\r\n testItBlock: this.testItBlock,\r\n interceptorsBlock: this.interceptorsBlock,\r\n saveButtonEnabled: this.saveButtonEnabled,\r\n isCreatingFile: this.isCreatingFile,\r\n collapsedDirs: this.collapsedDirs,\r\n sidebarWidth: this.sidebarWidth,\r\n }, this.t.bind(this))}`;\r\n\r\n this.shadow.querySelectorAll('[data-file]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n const data = (el as HTMLElement).dataset['file'];\r\n if (data) this.onFileClick(JSON.parse(data));\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-dir-path]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n const path = (el as HTMLElement).dataset['dirPath'];\r\n if (path) this.toggleDir(path);\r\n });\r\n });\r\n this.setupResizeHandle();\r\n this.shadow.getElementById('btn-save')\r\n ?.addEventListener('click', () => this.saveCommandsToFile());\r\n this.shadow.getElementById('btn-edit')\r\n ?.addEventListener('click', () => this.openEditManually());\r\n this.shadow.getElementById('btn-copy-it')\r\n ?.addEventListener('click', () => this.copyToClipboard(this.testItBlock));\r\n this.shadow.getElementById('btn-copy-interceptors')\r\n ?.addEventListener('click', () => this.copyToClipboard(this.interceptorsBlock));\r\n this.shadow.getElementById('btn-close')\r\n ?.addEventListener('click', () => this.closePreview());\r\n this.shadow.getElementById('btn-new-file')\r\n ?.addEventListener('click', () => {\r\n this.isCreatingFile = !this.isCreatingFile;\r\n this.render();\r\n if (this.isCreatingFile) this.shadow.getElementById('input-new-file')?.focus();\r\n });\r\n this.shadow.getElementById('btn-refresh')\r\n ?.addEventListener('click', () => this.refreshTree());\r\n this.shadow.getElementById('btn-new-file-confirm')\r\n ?.addEventListener('click', () => {\r\n const input = this.shadow.getElementById('input-new-file') as HTMLInputElement | null;\r\n this.createNewFile(input?.value ?? '');\r\n });\r\n this.shadow.getElementById('btn-new-file-cancel')\r\n ?.addEventListener('click', () => {\r\n this.isCreatingFile = false;\r\n this.render();\r\n });\r\n const input = this.shadow.getElementById('input-new-file') as HTMLInputElement | null;\r\n input?.addEventListener('keydown', (e) => {\r\n if (e.key === 'Enter') {\r\n this.createNewFile(input.value);\r\n } else if (e.key === 'Escape') {\r\n this.isCreatingFile = false;\r\n this.render();\r\n }\r\n });\r\n }\r\n}\r\n\r\nif (!customElements.get('advanced-test-editor')) {\r\n customElements.define('advanced-test-editor', AdvancedTestEditorElement);\r\n}\r\n","export const FILE_PREVIEW_STYLES = `\n :host { display: block; height: 100%; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }\n * { box-sizing: border-box; }\n .container { display: flex; flex-direction: column; height: 100%; }\n .header {\n display: flex; align-items: center; gap: 8px;\n padding: 8px 12px; border-bottom: 1px solid #21262d;\n background: #161b22;\n }\n .file-name { flex: 1; font-size: 12px; color: #8b949e;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; }\n .body { display: flex; flex: 1; overflow: hidden; min-height: 0; }\n .editor {\n flex: 1; min-width: 0; padding: 14px;\n background: #0d1117; color: #c9d1d9; border: none; outline: none;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 12px;\n line-height: 1.7; resize: none;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .editor::-webkit-scrollbar { width: 5px; }\n .editor::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }\n .blocks-panel {\n width: 260px; flex-shrink: 0; border-left: 1px solid #21262d;\n background: #0d1117; padding: 10px 12px; overflow-y: auto;\n display: flex; flex-direction: column; gap: 10px;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .blocks-panel::-webkit-scrollbar { width: 4px; }\n .blocks-panel::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .block-section { display: flex; flex-direction: column; gap: 4px; }\n .block-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 2px; }\n .block-label { font-size: 10px; color: #484f58; text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600; }\n .btn-copy-sm {\n padding: 2px 8px; border: 1px solid #30363d; border-radius: 4px; cursor: pointer;\n font-size: 10px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap;\n }\n .btn-copy-sm:hover { background: #30363d; color: #e6edf3; }\n .block-pre {\n margin: 0; padding: 6px 8px; background: #161b22;\n border-radius: 5px; border: 1px solid #21262d;\n font-size: 10px; color: #c9d1d9; line-height: 1.6;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n max-height: 280px; overflow-y: auto; white-space: pre-wrap; word-break: break-all;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .diff-panel {\n flex: 1; overflow-y: auto; background: #0d1117; border-left: 1px solid #21262d;\n padding: 8px 0; min-width: 0;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 11px;\n line-height: 1.6;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .diff-panel::-webkit-scrollbar { width: 5px; }\n .diff-panel::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }\n .diff-line {\n display: flex; gap: 0; white-space: pre; padding: 0 12px;\n }\n .diff-line.added { background: rgba(63,185,80,0.12); color: #3fb950; }\n .diff-line.removed { background: rgba(248,81,73,0.1); color: #f85149; }\n .diff-line.same { color: #484f58; }\n .diff-sign { width: 14px; flex-shrink: 0; user-select: none; }\n .diff-empty { color: #484f58; font-size: 12px; padding: 20px; text-align: center; }\n .footer {\n display: flex; gap: 8px; padding: 8px 12px;\n border-top: 1px solid #21262d; justify-content: flex-end;\n background: #161b22;\n }\n button {\n padding: 6px 14px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s;\n }\n button:hover { background: #30363d; color: #e6edf3; }\n .btn-save { background: #3fb950; border-color: #3fb950; color: #fff; }\n .btn-save:hover { background: #2ea043; border-color: #2ea043; }\n .btn-launch { background: transparent; border-color: #e3b341; color: #e3b341; }\n .btn-launch:hover { background: rgba(227,179,65,0.1); }\n .btn-diff-active { background: rgba(47,129,247,0.15); border-color: rgba(47,129,247,0.4); color: #2f81f7; }\n`;\n","import { escHtml } from '../../utils/html.utils';\n\nexport type DiffEntry = { type: 'same' | 'added' | 'removed'; line: string };\n\nexport function computeDiff(original: string, modified: string): DiffEntry[] {\n const MAX_LINES = 600;\n const a = original.split('\\n').slice(0, MAX_LINES);\n const b = modified.split('\\n').slice(0, MAX_LINES);\n const m = a.length, n = b.length;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]);\n }\n }\n\n const result: DiffEntry[] = [];\n let i = m, j = n;\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n result.unshift({ type: 'same', line: a[i - 1] });\n i--; j--;\n } else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {\n result.unshift({ type: 'added', line: b[j - 1] });\n j--;\n } else {\n result.unshift({ type: 'removed', line: a[i - 1] });\n i--;\n }\n }\n return result;\n}\n\nexport function buildDiffHtml(original: string, current: string, t: (key: string) => string): string {\n if (original === current) return `<div class=\"diff-empty\">${t('FILE_PREVIEW.NO_CHANGES')}</div>`;\n\n const diff = computeDiff(original, current);\n if (!diff.length) return `<div class=\"diff-empty\">${t('FILE_PREVIEW.NO_CHANGES_SHORT')}</div>`;\n\n const CONTEXT = 2;\n const compressed: DiffEntry[] = [];\n let sameRun = 0;\n for (let idx = 0; idx < diff.length; idx++) {\n if (diff[idx].type === 'same') {\n sameRun++;\n if (sameRun <= CONTEXT) compressed.push(diff[idx]);\n else if (idx + 1 < diff.length && diff[idx + 1].type !== 'same') {\n if (sameRun > CONTEXT * 2) compressed.push({ type: 'same', line: '…' });\n compressed.push(diff[idx]);\n }\n } else {\n sameRun = 0;\n compressed.push(diff[idx]);\n }\n }\n\n return compressed.map(({ type, line }) => {\n const sign = type === 'added' ? '+' : type === 'removed' ? '−' : ' ';\n return `<div class=\"diff-line ${type}\"><span class=\"diff-sign\">${sign}</span><span>${escHtml(line)}</span></div>`;\n }).join('');\n}\n\nexport interface FilePreviewState {\n fileName: string | null;\n showDiff: boolean;\n fileContent: string | null;\n originalContent: string | null;\n currentContent: string;\n itBlock: string;\n interceptorsBlock: string;\n closeLabel: string;\n}\n\nexport function renderFilePreview(state: FilePreviewState, t: (key: string) => string): string {\n const { fileName, showDiff, fileContent, originalContent, currentContent, itBlock, interceptorsBlock, closeLabel } = state;\n\n const blocksPanelHtml = (itBlock || interceptorsBlock) ? `\n <div class=\"blocks-panel\">\n ${itBlock ? `\n <div class=\"block-section\">\n <div class=\"block-row\">\n <span class=\"block-label\">${t('FILE_PREVIEW.BLOCK_IT')}</span>\n <button id=\"btn-copy-it\" class=\"btn-copy-sm\">${t('FILE_PREVIEW.COPY_BTN')}</button>\n </div>\n <pre class=\"block-pre\">${escHtml(itBlock.slice(0, 2000))}</pre>\n </div>` : ''}\n ${interceptorsBlock ? `\n <div class=\"block-section\">\n <div class=\"block-row\">\n <span class=\"block-label\">${t('FILE_PREVIEW.BLOCK_BEFORE_EACH')}</span>\n <button id=\"btn-copy-icp\" class=\"btn-copy-sm\">${t('FILE_PREVIEW.COPY_BTN')}</button>\n </div>\n <pre class=\"block-pre\" style=\"color:#3fb950\">${escHtml(interceptorsBlock.slice(0, 2000))}</pre>\n </div>` : ''}\n </div>` : '';\n\n const hasChanges = originalContent !== null && originalContent !== (fileContent ?? '');\n\n return `\n <div class=\"container\">\n <div class=\"header\">\n <span class=\"file-name\">📄 ${fileName ? escHtml(fileName) : t('FILE_PREVIEW.NO_FILE')}</span>\n <button id=\"btn-copy\" title=\"${t('FILE_PREVIEW.COPY_TITLE')}\">📋</button>\n </div>\n <div class=\"body\">\n ${showDiff\n ? `<div class=\"diff-panel\" id=\"diff-panel\">${buildDiffHtml(originalContent ?? '', currentContent, t)}</div>`\n : `<textarea class=\"editor\" id=\"editor\" spellcheck=\"false\">${escHtml(fileContent ?? '')}</textarea>`}\n ${blocksPanelHtml}\n </div>\n <div class=\"footer\">\n <button id=\"btn-launch\" class=\"btn-launch\">${t('FILE_PREVIEW.LAUNCH_BTN')}</button>\n ${hasChanges ? `<button id=\"btn-diff\" class=\"${showDiff ? 'btn-diff-active' : ''}\">${t('FILE_PREVIEW.DIFF_BTN')}</button>` : ''}\n <button id=\"btn-save\" class=\"btn-save\">${t('FILE_PREVIEW.SAVE_BTN')}</button>\n <button id=\"btn-close\">${escHtml(closeLabel || t('FILE_PREVIEW.CLOSE_BTN'))}</button>\n </div>\n </div>`;\n}\n","import { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { FILE_PREVIEW_STYLES } from './file-preview.styles';\r\nimport { renderFilePreview } from './file-preview.template';\r\n\r\nexport class FilePreviewElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private textarea: HTMLTextAreaElement | null = null;\r\n\r\n fileName: string | null = null;\r\n closeLabel = '';\r\n translation: TranslationService = translationService;\r\n itBlock = '';\r\n interceptorsBlock = '';\r\n commands: string[] = [];\r\n interceptors: string[] = [];\r\n private _fileContent: string | null = null;\r\n private _originalContent: string | null = null;\r\n private _showDiff = false;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.closeLabel) this.closeLabel = this.translation.translate('FILE_PREVIEW.CLOSE_BTN');\r\n this.render();\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n get fileContent(): string | null { return this._fileContent; }\r\n set fileContent(v: string | null) {\r\n if (this._originalContent === null) this._originalContent = v;\r\n this._fileContent = v;\r\n if (this.textarea) this.textarea.value = v ?? '';\r\n else this.render();\r\n }\r\n\r\n saveFile(): void {\r\n const content = this.textarea?.value ?? this._fileContent ?? '';\r\n this.dispatchEvent(new CustomEvent('save', { detail: content, bubbles: true, composed: true }));\r\n }\r\n\r\n onClose(): void {\r\n this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));\r\n }\r\n\r\n async launchTest(specPath?: string): Promise<void> {\r\n const path = specPath ?? (this.fileName ? `cypress/e2e/${this.fileName}` : '');\r\n if (!path) return;\r\n const response = await fetch('http://localhost:8123/run-test', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ specPath: path }),\r\n });\r\n await response.json();\r\n }\r\n\r\n copyToClipboard(text: string): void {\r\n navigator.clipboard?.writeText(text);\r\n }\r\n\r\n toggleDiff(): void {\r\n this._showDiff = !this._showDiff;\r\n this.render();\r\n }\r\n\r\n private render(): void {\r\n this.shadow.innerHTML = `<style>${FILE_PREVIEW_STYLES}</style>${renderFilePreview({\r\n fileName: this.fileName,\r\n showDiff: this._showDiff,\r\n fileContent: this._fileContent,\r\n originalContent: this._originalContent,\r\n currentContent: this.textarea?.value ?? this._fileContent ?? '',\r\n itBlock: this.itBlock,\r\n interceptorsBlock: this.interceptorsBlock,\r\n closeLabel: this.closeLabel,\r\n }, this.t.bind(this))}`;\r\n\r\n this.textarea = this.shadow.getElementById('editor') as HTMLTextAreaElement | null;\r\n if (this.textarea) {\r\n const ta = this.textarea;\r\n this.textarea.addEventListener('input', () => {\r\n this._fileContent = ta.value;\r\n });\r\n }\r\n this.shadow.getElementById('btn-save')?.addEventListener('click', () => this.saveFile());\r\n this.shadow.getElementById('btn-close')?.addEventListener('click', () => this.onClose());\r\n this.shadow.getElementById('btn-launch')?.addEventListener('click', () => this.launchTest());\r\n this.shadow.getElementById('btn-copy')?.addEventListener('click', () => {\r\n this.copyToClipboard(this.textarea?.value ?? this._fileContent ?? '');\r\n });\r\n this.shadow.getElementById('btn-diff')?.addEventListener('click', () => this.toggleDiff());\r\n this.shadow.getElementById('btn-copy-it')?.addEventListener('click', () => {\r\n this.copyToClipboard(this.itBlock);\r\n });\r\n this.shadow.getElementById('btn-copy-icp')?.addEventListener('click', () => {\r\n this.copyToClipboard(this.interceptorsBlock);\r\n });\r\n }\r\n}\r\n\r\nif (!customElements.get('file-preview')) {\r\n customElements.define('file-preview', FilePreviewElement);\r\n}\r\n","import Swal from 'sweetalert2';\r\nimport { getRecorderStyles } from './lib-e2e-recorder.styles';\r\nimport { renderRecorderWidget } from './lib-e2e-recorder.template';\r\nimport { RecordingService, type SelectorStrategy } from '../../services/recording.service';\r\nimport { PersistenceService } from '../../services/persistence.service';\r\nimport { TranslationService } from '../../services/translation.service';\r\nimport { HttpMonitor } from '../../services/http-monitor';\r\nimport {\r\n injectStyles,\r\n LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES,\r\n SCROLLBAR_STYLES,\r\n} from '../../utils/styles.utils';\r\nimport {\r\n makeModalResizable,\r\n makeSwalDraggable,\r\n setSwal2DataCyAttribute,\r\n} from '../../utils/modal.utils';\r\nimport type { Lang } from '../../models/lang.model';\r\nimport { showToast } from '../../utils/toast.utils';\r\n\r\n/**\r\n * Minimal property/event shapes for dynamically-created child custom elements.\r\n * Not extending HTMLElement avoids conflicts with the strict EventListener signature;\r\n * cast to Node/HTMLElement only for actual DOM insertion.\r\n */\r\ninterface PrevisualizerEl {\r\n translation: TranslationService; commands: string[]; interceptors: string[]; editable: boolean;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void): void;\r\n}\r\ninterface TestEditorEl { persistence: PersistenceService; translation: TranslationService }\r\ninterface SaveTestEl {\r\n translation: TranslationService;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void): void;\r\n}\r\ninterface ConfigEl {\r\n persistence: PersistenceService; translation: TranslationService;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void): void;\r\n}\r\ninterface AdvancedEditorEl {\r\n persistence: PersistenceService; translation: TranslationService; testId?: number;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void | Promise<void>): void;\r\n}\r\ninterface FilePreviewEl {\r\n translation: TranslationService; fileContent: string | null; fileName: string | null;\r\n closeLabel: string; itBlock: string; interceptorsBlock: string;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void | Promise<void>): void;\r\n}\r\ninterface SelectorPickerEl {\r\n targetElement: HTMLElement; recording: RecordingService; translation: TranslationService;\r\n}\r\n\r\nexport class LibE2eRecorderElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private _isDisabled = false;\r\n private keydownHandler!: (e: KeyboardEvent) => void;\r\n private recordingUnsub?: () => void;\r\n private commandsUnsub?: () => void;\r\n private interceptorsUnsub?: () => void;\r\n private pauseUnsub?: () => void;\r\n private selectorNotFoundUnsub?: () => void;\r\n private controlFirstTimeData = true;\r\n private _previsualizerRef: { commands: string[]; interceptors: string[] } | null = null;\r\n private httpMonitor?: HttpMonitor;\r\n private smartSelectorEnabled = true;\r\n\r\n recording!: RecordingService;\r\n persistence!: PersistenceService;\r\n translation!: TranslationService;\r\n\r\n isRecording = false;\r\n isPaused = false;\r\n cypressCommands: string[] = [];\r\n interceptors: string[] = [];\r\n\r\n isCommandsDialogOpen = false;\r\n isSavedTestsDialogOpen = false;\r\n isSaveTestDialogOpen = false;\r\n isSettingsDialogOpen = false;\r\n isAdvancedEditorDialogOpen = false;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if ('Cypress' in window) {\r\n this._isDisabled = true;\r\n return;\r\n }\r\n if (!this.getAttribute('data-cy')) {\r\n this.setAttribute('data-cy', 'lib-e2e-cypress-for-dummys');\r\n }\r\n if (!this.recording) this.recording = new RecordingService();\r\n if (!this.persistence) this.persistence = new PersistenceService();\r\n if (!this.translation) this.translation = new TranslationService();\r\n\r\n this.httpMonitor = new HttpMonitor(this.recording);\r\n this.httpMonitor.install();\r\n\r\n injectStyles(LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES, 'lib-e2e-swal2-styles');\r\n injectStyles(SCROLLBAR_STYLES, 'lib-e2e-scrollbar-styles');\r\n\r\n this.initHttpConfig();\r\n this.initLanguage();\r\n this.initFilesystemAccess();\r\n this.initSelectorStrategy();\r\n this.initSubscriptions();\r\n this.render();\r\n\r\n this.keydownHandler = (e: KeyboardEvent) => this.handleKeyboardEvent(e);\r\n window.addEventListener('keydown', this.keydownHandler);\r\n }\r\n\r\n disconnectedCallback(): void {\r\n if (this._isDisabled) return;\r\n window.removeEventListener('keydown', this.keydownHandler);\r\n this.recordingUnsub?.();\r\n this.commandsUnsub?.();\r\n this.interceptorsUnsub?.();\r\n this.pauseUnsub?.();\r\n this.selectorNotFoundUnsub?.();\r\n this.httpMonitor?.uninstall();\r\n this.recording.destroy();\r\n }\r\n\r\n private async initHttpConfig(): Promise<void> {\r\n const config = await this.persistence.getConfig('extendedHttpCommands');\r\n if (config === null) {\r\n await this.persistence.setConfig({ extendedHttpCommands: 'true' });\r\n localStorage.setItem('extendedHttpCommands', 'true');\r\n } else {\r\n localStorage.setItem('extendedHttpCommands', (config['extendedHttpCommands'] as string) ?? 'true');\r\n }\r\n }\r\n\r\n private async initLanguage(): Promise<void> {\r\n const config = await this.persistence.getConfig('language');\r\n const lang = config?.['language'] as Lang | undefined;\r\n this.translation.setLang(lang ?? this.translation.detectLang());\r\n }\r\n\r\n private initSubscriptions(): void {\r\n this.recordingUnsub = this.recording.onRecordingChange((val) => {\r\n this.isRecording = val;\r\n if (!val && !this.controlFirstTimeData) {\r\n this.saveRecordingHistory();\r\n this.showSaveTestDialog();\r\n }\r\n this.controlFirstTimeData = false;\r\n this.render();\r\n });\r\n this.commandsUnsub = this.recording.onCommandsChange((cmds) => {\r\n this.cypressCommands = cmds;\r\n if (this._previsualizerRef) this._previsualizerRef.commands = cmds;\r\n });\r\n this.interceptorsUnsub = this.recording.onInterceptorsChange((icps) => {\r\n this.interceptors = icps;\r\n if (this._previsualizerRef) this._previsualizerRef.interceptors = icps;\r\n });\r\n this.pauseUnsub = this.recording.onPauseChange((paused) => {\r\n this.isPaused = paused;\r\n this.render();\r\n });\r\n this.selectorNotFoundUnsub = this.recording.onSelectorNotFound((target) => {\r\n if (this.smartSelectorEnabled) this.showSelectorPicker(target);\r\n });\r\n }\r\n\r\n private showSelectorPicker(target: HTMLElement): void {\r\n import('../../components/selector-picker/selector-picker').then(() => {\r\n const existing = document.querySelector('selector-picker');\r\n if (existing) existing.remove();\r\n\r\n const picker = document.createElement('selector-picker') as unknown as SelectorPickerEl;\r\n picker.targetElement = target;\r\n picker.recording = this.recording;\r\n picker.translation = this.translation;\r\n document.body.appendChild(picker as unknown as Node);\r\n });\r\n }\r\n\r\n private async initSelectorStrategy(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig();\r\n const strategy = config?.['selectorStrategy'] as string | undefined;\r\n if (strategy) this.recording.selectorStrategy = strategy as SelectorStrategy;\r\n this.smartSelectorEnabled = config?.['smartSelectorEnabled'] !== 'false';\r\n }\r\n\r\n toggle(): void {\r\n this.recording.toggleRecording();\r\n }\r\n\r\n togglePause(): void {\r\n this.recording.togglePause();\r\n }\r\n\r\n setLanguage(lang?: string): void {\r\n const resolved = lang ? (lang as Lang) : this.translation.detectLang();\r\n this.translation.setLang(resolved);\r\n }\r\n\r\n handleKeyboardEvent(event: KeyboardEvent): void {\r\n if (!event.ctrlKey) return;\r\n const key = event.key.toLowerCase();\r\n if (key === 'r') { event.preventDefault(); this.toggle(); }\r\n else if (key === 'p') { event.preventDefault(); this.togglePause(); }\r\n else if (key === '1') { event.preventDefault(); this.showSavedTestsDialog(); }\r\n else if (key === '2') { event.preventDefault(); this.showCommandsDialog(); }\r\n else if (key === '3') { event.preventDefault(); this.showSettingsDialog(); }\r\n }\r\n\r\n // ── recording history (task 5) ────────────────────────────────────────────\r\n\r\n private saveRecordingHistory(): void {\r\n if (!this.cypressCommands.length) return;\r\n try {\r\n const existing = JSON.parse(localStorage.getItem('e2e-recording-history') ?? '[]');\r\n existing.unshift({ commands: this.cypressCommands, interceptors: this.interceptors, savedAt: Date.now() });\r\n if (existing.length > 5) existing.splice(5);\r\n localStorage.setItem('e2e-recording-history', JSON.stringify(existing));\r\n } catch { /* ignore storage errors */ }\r\n }\r\n\r\n recoverLastRecording(): void {\r\n try {\r\n const existing = JSON.parse(localStorage.getItem('e2e-recording-history') ?? '[]');\r\n if (!existing.length) return;\r\n const { commands, interceptors } = existing[0];\r\n commands.forEach((cmd: string) => this.recording.appendCommand(cmd));\r\n (interceptors as string[]).forEach((_icp: string) => { /* interceptors are not appendable the same way */ });\r\n } catch { /* ignore */ }\r\n }\r\n\r\n clearRecordingHistory(): void {\r\n localStorage.removeItem('e2e-recording-history');\r\n }\r\n\r\n getRecordingHistory(): Array<{ commands: string[]; interceptors: string[]; savedAt: number }> {\r\n try {\r\n return JSON.parse(localStorage.getItem('e2e-recording-history') ?? '[]');\r\n } catch { return []; }\r\n }\r\n\r\n // ── filesystem setup ─────────────────────────────────────────────────────\r\n\r\n private async initFilesystemAccess(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig();\r\n // Only show if the user has never made a choice (key doesn't exist yet)\r\n if (config && 'allowReadWriteFiles' in config) return;\r\n this.showFilesystemSetupDialog();\r\n }\r\n\r\n private showFilesystemSetupDialog(): void {\r\n Swal.fire({\r\n title: this.translation.translate('RECORDER.FS_TITLE'),\r\n html: '<div id=\"fs-setup-content\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('fs-setup-content');\r\n if (!container) return;\r\n container.innerHTML = `\r\n <div style=\"padding:16px 20px 20px;color:#8b949e;font-size:13px;line-height:1.7\">\r\n <p>${this.translation.translate('RECORDER.FS_INTRO_HTML')}</p>\r\n <p style=\"margin-top:10px;margin-bottom:6px;font-size:11px;color:#8b949e\">\r\n ${this.translation.translate('RECORDER.FS_STRUCTURE_HINT_HTML')}\r\n </p>\r\n <pre style=\"margin:0;padding:10px 14px;background:#0d1117;border:1px solid #21262d;\r\n border-radius:8px;font-size:11px;color:#c9d1d9;line-height:1.8;\r\n font-family:'Cascadia Code','Fira Code','Consolas',monospace\">\r\ncypress/ <span style=\"color:#484f58\">${this.translation.translate('RECORDER.FS_TREE_PICK_HINT')}</span>\r\n└── e2e/ <span style=\"color:#484f58\">${this.translation.translate('RECORDER.FS_TREE_READ_HINT')}</span>\r\n └── *.cy.ts</pre>\r\n <p style=\"margin-top:8px;font-size:11px;color:#484f58\">\r\n ${this.translation.translate('RECORDER.FS_PERMISSION_NOTE')}\r\n </p>\r\n <div style=\"display:flex;gap:8px;justify-content:flex-end;margin-top:20px\">\r\n <button id=\"fs-skip\"\r\n style=\"padding:7px 16px;border:1px solid #30363d;border-radius:6px;cursor:pointer;\r\n font-size:12px;font-weight:500;background:transparent;color:#8b949e\">\r\n ${this.translation.translate('RECORDER.FS_LATER_BTN')}\r\n </button>\r\n <button id=\"fs-select\"\r\n style=\"padding:7px 16px;border:none;border-radius:6px;cursor:pointer;\r\n font-size:12px;font-weight:500;background:#2f81f7;color:#fff\">\r\n ${this.translation.translate('RECORDER.FS_SELECT_BTN')}\r\n </button>\r\n </div>\r\n </div>`;\r\n\r\n document.getElementById('fs-skip')?.addEventListener('click', async () => {\r\n await this.persistence.setConfigKey('allowReadWriteFiles', 'false');\r\n Swal.close();\r\n });\r\n\r\n document.getElementById('fs-select')?.addEventListener('click', async () => {\r\n try {\r\n await this.persistence.requestDirectoryPermissions();\r\n Swal.close();\r\n showToast(this.translation.translate('RECORDER.FS_SUCCESS_TOAST'));\r\n } catch (e: unknown) {\r\n if ((e as DOMException)?.name !== 'AbortError') {\r\n showToast(this.translation.translate('RECORDER.FS_ERROR_TOAST'), false);\r\n }\r\n // AbortError = user cancelled the picker, leave dialog open\r\n }\r\n });\r\n },\r\n });\r\n }\r\n\r\n // ── dialogs ──────────────────────────────────────────────────────────────\r\n\r\n showCommandsDialog(): void {\r\n this.toggleModal('isCommandsDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.DIALOG_COMMANDS'),\r\n html: '<div id=\"commands-modal-content\" style=\"min-height:250px;padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n backdrop: false,\r\n width: 640,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n // Make the container click-through so the page underneath remains interactive\r\n const swalContainer = document.querySelector('.swal2-container') as HTMLElement | null;\r\n if (swalContainer) {\r\n swalContainer.style.pointerEvents = 'none';\r\n const popup = swalContainer.querySelector('.swal2-popup') as HTMLElement | null;\r\n if (popup) popup.style.pointerEvents = 'all';\r\n }\r\n const container = document.getElementById('commands-modal-content');\r\n if (!container) return;\r\n\r\n const child = document.createElement('test-previsualizer') as unknown as PrevisualizerEl;\r\n child.translation = this.translation;\r\n child.commands = this.cypressCommands;\r\n child.interceptors = this.interceptors;\r\n child.editable = true;\r\n container.appendChild(child as unknown as Node);\r\n this._previsualizerRef = child;\r\n\r\n child.addEventListener('deletecommand', (e: CustomEvent) => {\r\n this.recording.removeCommand(e.detail);\r\n });\r\n child.addEventListener('movecommand', (e: CustomEvent) => {\r\n this.recording.moveCommand(e.detail.from, e.detail.to);\r\n });\r\n child.addEventListener('deleteinterceptor', (e: CustomEvent) => {\r\n this.recording.removeInterceptor(e.detail);\r\n });\r\n\r\n // ── Assertion builder panel ──────────────────────────────────────\r\n const assertionHtml = `\r\n <div id=\"assertion-builder\"\r\n style=\"padding:10px 12px;border-top:1px solid #21262d;background:#0d1117\">\r\n <div style=\"font-size:10px;color:#484f58;text-transform:uppercase;letter-spacing:.8px;font-weight:600;margin-bottom:8px\">\r\n ${this.translation.translate('RECORDER.ASSERTION_SECTION')}\r\n </div>\r\n <div style=\"display:flex;gap:6px;flex-wrap:wrap;align-items:flex-end\">\r\n <input id=\"assert-selector\" type=\"text\"\r\n placeholder=\"${this.translation.translate('RECORDER.ASSERT_SELECTOR_PH').replace(/\"/g, '&quot;')}\"\r\n style=\"flex:2;min-width:140px;padding:5px 8px;background:#161b22;border:1px solid #30363d;\r\n border-radius:5px;color:#c9d1d9;font-size:11px;outline:none;\r\n font-family:'Cascadia Code','Fira Code',monospace\"/>\r\n <select id=\"assert-type\"\r\n style=\"padding:5px 8px;background:#161b22;border:1px solid #30363d;border-radius:5px;\r\n color:#c9d1d9;font-size:11px;outline:none;cursor:pointer;flex-shrink:0\">\r\n <option value=\"be.visible\">be.visible</option>\r\n <option value=\"not.exist\">not.exist</option>\r\n <option value=\"be.disabled\">be.disabled</option>\r\n <option value=\"be.checked\">be.checked</option>\r\n <option value=\"contain.text\">contain.text</option>\r\n <option value=\"have.value\">have.value</option>\r\n <option value=\"have.length\">have.length</option>\r\n <option value=\"have.class\">have.class</option>\r\n <option value=\"have.attr\">have.attr</option>\r\n </select>\r\n <input id=\"assert-value\" type=\"text\" placeholder=\"${this.translation.translate('RECORDER.ASSERT_VALUE_PH')}\"\r\n style=\"flex:2;min-width:110px;padding:5px 8px;background:#161b22;border:1px solid #30363d;\r\n border-radius:5px;color:#c9d1d9;font-size:11px;outline:none\"/>\r\n <button id=\"btn-add-assertion\"\r\n style=\"padding:5px 12px;border:none;border-radius:5px;cursor:pointer;\r\n font-size:11px;font-weight:500;background:#2f81f7;color:#fff;\r\n white-space:nowrap;flex-shrink:0\">\r\n ${this.translation.translate('RECORDER.ASSERT_ADD_BTN')}\r\n </button>\r\n </div>\r\n </div>`;\r\n container.insertAdjacentHTML('beforeend', assertionHtml);\r\n\r\n const NO_VALUE_ASSERTIONS = new Set(['be.visible', 'not.exist', 'be.disabled', 'be.checked']);\r\n document.getElementById('btn-add-assertion')?.addEventListener('click', () => {\r\n const sel = (document.getElementById('assert-selector') as HTMLInputElement).value.trim();\r\n const type = (document.getElementById('assert-type') as HTMLSelectElement).value;\r\n const val = (document.getElementById('assert-value') as HTMLInputElement).value.trim();\r\n if (!sel) return;\r\n const cmd = NO_VALUE_ASSERTIONS.has(type) || !val\r\n ? `cy.get('${sel}').should('${type}')`\r\n : `cy.get('${sel}').should('${type}', '${val}')`;\r\n this.recording.appendCommand(cmd);\r\n (document.getElementById('assert-selector') as HTMLInputElement).value = '';\r\n (document.getElementById('assert-value') as HTMLInputElement).value = '';\r\n });\r\n },\r\n willClose: () => {\r\n this.isCommandsDialogOpen = false;\r\n this._previsualizerRef = null;\r\n },\r\n });\r\n this.resizePopup();\r\n });\r\n }\r\n\r\n showSavedTestsDialog(): void {\r\n this.toggleModal('isSavedTestsDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.DIALOG_SAVED_TESTS'),\r\n html: '<div id=\"saved-tests-modal-content\" style=\"min-height:250px;padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n width: 680,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('saved-tests-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('test-editor') as unknown as TestEditorEl;\r\n child.persistence = this.persistence;\r\n child.translation = this.translation;\r\n container.appendChild(child as unknown as Node);\r\n },\r\n willClose: () => { this.isSavedTestsDialogOpen = false; },\r\n });\r\n this.resizePopup();\r\n });\r\n }\r\n\r\n showSaveTestDialog(): void {\r\n this.toggleModal('isSaveTestDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.DIALOG_SAVE'),\r\n html: '<div id=\"save-test-modal-content\" style=\"padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('save-test-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('save-test') as unknown as SaveTestEl;\r\n child.translation = this.translation;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('savetest', (e: CustomEvent) => {\r\n const { description, tags } = e.detail ?? {};\r\n this.onSaveTest(description ?? null, tags ?? []);\r\n Swal.close();\r\n });\r\n child.addEventListener('saveandexport', (e: CustomEvent) => {\r\n const { description, tags } = e.detail ?? {};\r\n this.onSaveAndExportTest(description ?? null, tags ?? []);\r\n Swal.close();\r\n });\r\n },\r\n willClose: () => { this.isSaveTestDialogOpen = false; },\r\n });\r\n });\r\n }\r\n\r\n showSettingsDialog(): void {\r\n this.toggleModal('isSettingsDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.SETTINGS'),\r\n html: '<div id=\"settings-modal-content\" style=\"padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n width: 520,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('settings-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('e2e-configuration') as unknown as ConfigEl;\r\n child.persistence = this.persistence;\r\n child.translation = this.translation;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('smartselectorchange', (e: CustomEvent) => {\r\n this.smartSelectorEnabled = e.detail;\r\n });\r\n },\r\n willClose: () => { this.isSettingsDialogOpen = false; },\r\n });\r\n this.resizePopup();\r\n });\r\n }\r\n\r\n showAdvancedEditorDialog(testId?: number): void {\r\n this.toggleModal('isAdvancedEditorDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.SHOW_ADVANCED_EDITOR'),\r\n html: '<div id=\"advanced-editor-modal-content\" style=\"flex:1;min-height:0;display:flex;flex-direction:column;padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n width: 780,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const popup = Swal.getPopup();\r\n if (popup) {\r\n popup.style.height = '600px';\r\n const htmlContainer = popup.querySelector('.swal2-html-container') as HTMLElement | null;\r\n if (htmlContainer) {\r\n htmlContainer.style.flex = '1';\r\n htmlContainer.style.minHeight = '0';\r\n htmlContainer.style.overflow = 'hidden';\r\n htmlContainer.style.padding = '0';\r\n htmlContainer.style.margin = '0';\r\n htmlContainer.style.display = 'flex';\r\n htmlContainer.style.flexDirection = 'column';\r\n }\r\n }\r\n const container = document.getElementById('advanced-editor-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('advanced-test-editor') as unknown as AdvancedEditorEl;\r\n child.persistence = this.persistence;\r\n child.translation = this.translation;\r\n if (testId !== undefined) child.testId = testId;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('selectorstrategychange', (e: CustomEvent) => {\r\n this.recording.selectorStrategy = e.detail;\r\n });\r\n child.addEventListener('closemodal', () => Swal.close());\r\n child.addEventListener('openfileeditor', (e: CustomEvent) => {\r\n Swal.close();\r\n setTimeout(() => this.showFileEditorDialog(\r\n e.detail.handle, e.detail.content, e.detail.fileName, e.detail.testId,\r\n e.detail.itBlock, e.detail.interceptorsBlock,\r\n ), 150);\r\n });\r\n },\r\n willClose: () => { this.isAdvancedEditorDialogOpen = false; },\r\n });\r\n setTimeout(() => {\r\n const popup = Swal.getPopup();\r\n if (popup) makeModalResizable(popup, { minWidth: 400, minHeight: 0 });\r\n }, 0);\r\n });\r\n }\r\n\r\n private showFileEditorDialog(\r\n handle: FileSystemFileHandle,\r\n content: string,\r\n fileName: string,\r\n testId?: number,\r\n itBlock = '',\r\n interceptorsBlock = '',\r\n ): void {\r\n Swal.fire({\r\n title: this.translation.translate('RECORDER.FILE_EDITOR_TITLE'),\r\n html: '<div id=\"file-editor-modal-content\" style=\"padding:0;height:540px\"></div>',\r\n showCloseButton: false,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n width: 1100,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('file-editor-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('file-preview') as unknown as FilePreviewEl;\r\n child.translation = this.translation;\r\n child.fileContent = content;\r\n child.fileName = fileName;\r\n child.closeLabel = this.translation.translate('FILE_PREVIEW.BACK_TO_EDITOR');\r\n child.itBlock = itBlock;\r\n child.interceptorsBlock = interceptorsBlock;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('close', () => {\r\n Swal.close();\r\n setTimeout(() => this.showAdvancedEditorDialog(testId), 150);\r\n });\r\n child.addEventListener('save', async (e: CustomEvent) => {\r\n try {\r\n const writable = await handle.createWritable();\r\n await writable.write(e.detail);\r\n await writable.close();\r\n showToast(this.translation.translate('RECORDER.FILE_SAVED_TOAST'));\r\n } catch {\r\n showToast(this.translation.translate('RECORDER.FILE_SAVE_ERROR_TOAST'), false);\r\n }\r\n Swal.close();\r\n setTimeout(() => this.showAdvancedEditorDialog(testId), 150);\r\n });\r\n },\r\n });\r\n this.resizePopup();\r\n }\r\n\r\n // ── save handlers ─────────────────────────────────────────────────────────\r\n\r\n private async onSaveTest(description: string | null, tags: string[] = []): Promise<void> {\r\n if (description) {\r\n await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags);\r\n this.recording.clearCommands();\r\n this.clearRecordingHistory();\r\n this.cypressCommands = [];\r\n this.interceptors = [];\r\n }\r\n }\r\n\r\n private async onSaveAndExportTest(description: string | null, tags: string[] = []): Promise<void> {\r\n if (description) {\r\n const id = await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags);\r\n this.recording.clearCommands();\r\n this.clearRecordingHistory();\r\n this.cypressCommands = [];\r\n this.interceptors = [];\r\n setTimeout(() => this.showAdvancedEditorDialog(id), 300);\r\n }\r\n }\r\n\r\n // ── helpers ───────────────────────────────────────────────────────────────\r\n\r\n private toggleModal(flag: keyof this, openFn: () => void): void {\r\n if (this[flag]) {\r\n Swal.close();\r\n (this as Record<string, unknown>)[flag as string] = false;\r\n return;\r\n }\r\n (this as Record<string, unknown>)[flag as string] = true;\r\n openFn();\r\n }\r\n\r\n private resizePopup(): void {\r\n setTimeout(() => {\r\n const popup = Swal.getPopup();\r\n if (popup) makeModalResizable(popup, { minWidth: 400, minHeight: 200 });\r\n }, 0);\r\n }\r\n\r\n private render(): void {\r\n const rec = this.isRecording;\r\n const paused = this.isPaused;\r\n this.shadow.innerHTML = `<style>${getRecorderStyles(rec, paused)}</style>${renderRecorderWidget(rec, paused, this.translation.translate.bind(this.translation))}`;\r\n this.shadow.querySelector('[data-action=\"toggle\"]')\r\n ?.addEventListener('click', () => this.toggle());\r\n this.shadow.querySelector('[data-action=\"pause\"]')\r\n ?.addEventListener('click', () => this.togglePause());\r\n this.shadow.querySelector('[data-action=\"tests\"]')\r\n ?.addEventListener('click', () => this.showSavedTestsDialog());\r\n this.shadow.querySelector('[data-action=\"commands\"]')\r\n ?.addEventListener('click', () => this.showCommandsDialog());\r\n this.shadow.querySelector('[data-action=\"config\"]')\r\n ?.addEventListener('click', () => this.showSettingsDialog());\r\n this.shadow.querySelector('[data-action=\"browse\"]')\r\n ?.addEventListener('click', () => this.showAdvancedEditorDialog());\r\n }\r\n}\r\n\r\nif (!customElements.get('lib-e2e-recorder')) {\r\n customElements.define('lib-e2e-recorder', LibE2eRecorderElement);\r\n}\r\n","export function getRecorderStyles(rec: boolean, paused: boolean): string {\n return `\n :host { all: initial; }\n *, *::before, *::after { box-sizing: border-box; }\n\n /*\n * Invisible 190×190 hit area anchored at bottom-right.\n * Keeps :hover alive while the cursor travels from the\n * toggle to any of the radial action buttons.\n */\n .widget {\n position: fixed;\n bottom: 0;\n right: 0;\n width: 190px;\n height: 190px;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n /* ── Toggle ──────────────────────────────────────── */\n .btn-toggle {\n position: absolute;\n bottom: 24px;\n right: 24px;\n width: 44px;\n height: 44px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n font-size: 19px;\n background: ${rec\n ? 'linear-gradient(135deg,#f85149 0%,#da3633 100%)'\n : 'linear-gradient(135deg,#2f81f7 0%,#1f6feb 100%)'};\n color: #fff;\n box-shadow: ${rec\n ? '0 4px 20px rgba(248,81,73,.55),0 0 0 4px rgba(248,81,73,.13)'\n : '0 4px 20px rgba(47,129,247,.45),0 0 0 4px rgba(47,129,247,.11)'};\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform .18s, box-shadow .2s;\n z-index: 2;\n ${rec ? 'animation: toggle-pulse 2s ease-in-out infinite;' : ''}\n }\n .btn-toggle:hover { transform: scale(1.1); }\n .btn-toggle:active { transform: scale(0.93); }\n\n @keyframes toggle-pulse {\n 0%,100% { box-shadow: 0 4px 20px rgba(248,81,73,.55),0 0 0 4px rgba(248,81,73,.13); }\n 50% { box-shadow: 0 6px 28px rgba(248,81,73,.75),0 0 0 8px rgba(248,81,73,.06); }\n }\n\n /* ── Pause button ────────────────────────────────── */\n .btn-pause {\n position: absolute;\n bottom: 78px;\n right: 24px;\n width: 34px;\n height: 34px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n font-size: 15px;\n display: ${rec ? 'flex' : 'none'};\n align-items: center;\n justify-content: center;\n background: ${paused\n ? 'linear-gradient(135deg,#2f81f7 0%,#1f6feb 100%)'\n : 'rgba(13,17,23,0.85)'};\n color: ${paused ? '#fff' : '#e3b341'};\n box-shadow: 0 2px 12px rgba(0,0,0,.4), 0 0 0 1px rgba(48,54,61,.8);\n transition: transform .15s, background .2s, color .2s;\n z-index: 2;\n }\n .btn-pause:hover { transform: scale(1.12); }\n .btn-pause:active { transform: scale(0.93); }\n\n /* ── Action buttons ──────────────────────────────── */\n /*\n * All three start centered on the toggle button\n * (toggle center = bottom:46px right:46px from widget edge;\n * button half = 18px → bottom:28px right:28px).\n */\n .btn-action {\n position: absolute;\n bottom: 28px;\n right: 28px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(13,17,23,.92);\n backdrop-filter: blur(14px);\n -webkit-backdrop-filter: blur(14px);\n color: #8b949e;\n box-shadow: 0 4px 18px rgba(0,0,0,.45), 0 0 0 1px rgba(48,54,61,.75);\n opacity: 0;\n transform: scale(0.35);\n pointer-events: none;\n /* Collapse: fast, no spring */\n transition: opacity .15s, transform .18s ease-in,\n background .15s, color .12s, box-shadow .15s;\n }\n\n /* Label to the left of each button */\n .btn-action::after {\n content: attr(data-label);\n position: absolute;\n right: calc(100% + 9px);\n top: 50%;\n transform: translateY(-50%);\n background: rgba(13,17,23,.95);\n color: #e6edf3;\n font-size: 11px;\n font-weight: 500;\n padding: 3px 9px;\n border-radius: 6px;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity .15s .05s;\n border: 1px solid rgba(48,54,61,.8);\n box-shadow: 0 2px 8px rgba(0,0,0,.35);\n }\n /* Button 1 (top) — label above instead of left to avoid overlap with btn 2 */\n .btn-action[data-n=\"1\"]::after {\n right: auto;\n left: 50%;\n top: auto;\n bottom: calc(100% + 9px);\n transform: translateX(-50%);\n }\n .btn-action:hover::after { opacity: 1; }\n .btn-action:hover { background: #21262d; color: #e6edf3; }\n .btn-action:active { background: #30363d !important; }\n\n /* Expand: spring + stagger */\n .widget:hover .btn-action {\n opacity: 1;\n pointer-events: all;\n transition: opacity .2s, transform .32s cubic-bezier(.34,1.56,.64,1),\n background .15s, color .12s, box-shadow .15s;\n }\n\n /* Arc positions — 4 buttons, 30° spacing, radius 90px */\n .widget:hover .btn-action[data-n=\"1\"] { /* 0° — straight up */\n transform: translateY(-90px) scale(1);\n transition-delay: .03s;\n }\n .widget:hover .btn-action[data-n=\"2\"] { /* 30° — upper-left */\n transform: translate(-45px,-78px) scale(1);\n transition-delay: .07s;\n }\n .widget:hover .btn-action[data-n=\"3\"] { /* 60° — left-upper */\n transform: translate(-78px,-45px) scale(1);\n transition-delay: .11s;\n }\n .widget:hover .btn-action[data-n=\"4\"] { /* 90° — straight left */\n transform: translateX(-90px) scale(1);\n transition-delay: .15s;\n }\n /* Button 4 (pure left) — label above to avoid going off-screen */\n .btn-action[data-n=\"4\"]::after {\n right: auto;\n left: 50%;\n top: auto;\n bottom: calc(100% + 9px);\n transform: translateX(-50%);\n }\n\n /* ── REC / PAUSED badge ──────────────────────────── */\n .rec-badge {\n position: fixed;\n top: 14px;\n left: 50%;\n transform: translateX(-50%);\n background: ${paused\n ? 'linear-gradient(90deg,#e3b341,#d29922)'\n : 'linear-gradient(90deg,#f85149,#da3633)'};\n color: #fff;\n padding: 3px 16px;\n border-radius: 20px;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 2px;\n text-transform: uppercase;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: ${paused\n ? '0 4px 16px rgba(227,179,65,.4)'\n : '0 4px 16px rgba(248,81,73,.4)'};\n display: ${rec ? 'block' : 'none'};\n ${!paused ? 'animation: rec-pulse 1.8s ease-in-out infinite;' : ''}\n }\n @keyframes rec-pulse {\n 0%,100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n `;\n}\n","export function renderRecorderWidget(rec: boolean, paused: boolean, t: (key: string) => string): string {\n return `\n <div class=\"widget\">\n <button class=\"btn-action\" data-n=\"1\" data-action=\"config\"\n data-label=\"${t('RECORDER.BTN_CONFIG')}\">⚙️</button>\n <button class=\"btn-action\" data-n=\"2\" data-action=\"browse\"\n data-label=\"${t('RECORDER.BTN_FILES')}\">📁</button>\n <button class=\"btn-action\" data-n=\"3\" data-action=\"commands\"\n data-label=\"${t('RECORDER.BTN_COMMANDS')}\">⌨️</button>\n <button class=\"btn-action\" data-n=\"4\" data-action=\"tests\"\n data-label=\"${t('RECORDER.BTN_TESTS')}\">📋</button>\n <button class=\"btn-pause\" data-action=\"pause\"\n title=\"${paused ? t('RECORDER.RESUME_TITLE') : t('RECORDER.PAUSE_TITLE')}\">\n ${paused ? '▶' : '⏸'}\n </button>\n <button class=\"btn-toggle\" data-action=\"toggle\"\n title=\"${rec ? t('RECORDER.STOP_TITLE') : t('RECORDER.START_TITLE')}\">\n ${rec ? '⏹' : '⏺'}\n </button>\n </div>\n <div class=\"rec-badge\">${paused ? t('RECORDER.BADGE_PAUSED') : t('RECORDER.BADGE_REC')}</div>`;\n}\n","// Public API — populated as migration phases are completed\r\nexport const VERSION = '0.1.0';\r\n\r\n// Phase 1 — Models\r\nexport * from './models/lang.model';\r\nexport * from './models/input-types.model';\r\nexport * from './models/db-schema.model';\r\n\r\n// Phase 2 — TranslationService\r\nexport * from './services/translation.service';\r\n\r\n// Phase 3 — Transformation Services\r\nexport * from './services/transformation.service';\r\nexport * from './services/advanced-test.transformation.service';\r\n\r\n// Phase 4 — RecordingService\r\nexport * from './utils/subject';\r\nexport * from './services/recording.service';\r\n\r\n// Phase 5 — PersistenceService\r\nexport * from './services/persistence.service';\r\n\r\n// Phase 6 — HttpMonitor\r\nexport * from './services/http-monitor';\r\n\r\n// Phase 7 — UI Utilities\r\nexport * from './utils/styles.utils';\r\nexport * from './utils/modal.utils';\r\nexport * from './utils/toast.utils';\r\n\r\n// Phase 8 — Web Components\r\nexport * from './components/test-previsualizer/test-previsualizer';\r\nexport * from './components/save-test/save-test';\r\nexport * from './components/test-editor/test-editor';\r\nexport * from './components/configuration/configuration';\r\nexport * from './components/advanced-test-editor/advanced-test-editor';\r\nexport * from './components/file-preview/file-preview';\r\nexport * from './components/lib-e2e-recorder/lib-e2e-recorder';\r\n"],"mappings":"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","names":["tag","container","rect","input","i","j"]}
1
+ {"version":3,"sources":["../src/models/lang.model.ts","../src/models/input-types.model.ts","../src/models/db-schema.model.ts","../src/i18n/es.ts","../src/i18n/en.ts","../src/i18n/fr.ts","../src/i18n/it.ts","../src/i18n/de.ts","../src/services/translation.service.ts","../src/utils/code-format.utils.ts","../src/services/transformation.service.ts","../src/services/advanced-test.transformation.service.ts","../src/utils/subject.ts","../src/services/recording.service.ts","../src/services/persistence.service.ts","../src/services/http-monitor.ts","../src/utils/styles.utils.ts","../src/utils/modal.utils.ts","../src/utils/toast.utils.ts","../src/components/test-previsualizer/test-previsualizer.styles.ts","../src/components/test-previsualizer/test-previsualizer.template.ts","../src/components/test-previsualizer/test-previsualizer.ts","../src/components/save-test/save-test.styles.ts","../src/components/save-test/save-test.template.ts","../src/components/save-test/save-test.ts","../src/components/test-editor/test-editor.styles.ts","../src/utils/syntax-highlight.utils.ts","../src/components/test-editor/test-editor.template.ts","../src/components/test-editor/test-editor.ts","../src/components/configuration/configuration.styles.ts","../src/components/configuration/configuration.template.ts","../src/components/configuration/configuration.ts","../src/components/advanced-test-editor/advanced-test-editor.styles.ts","../src/components/advanced-test-editor/advanced-test-editor.template.ts","../src/components/advanced-test-editor/advanced-test-editor.ts","../src/components/file-preview/file-preview.styles.ts","../src/components/file-preview/file-preview.template.ts","../src/components/file-preview/file-preview.ts","../src/components/lib-e2e-recorder/lib-e2e-recorder.ts","../src/components/lib-e2e-recorder/lib-e2e-recorder.styles.ts","../src/components/lib-e2e-recorder/lib-e2e-recorder.template.ts","../src/index.ts"],"sourcesContent":["export type Lang = 'es' | 'en' | 'fr' | 'it' | 'de';\r\n\r\nexport const SUPPORTED_LANGS: Lang[] = ['es', 'en', 'fr', 'it', 'de'];\r\n\r\nexport function isLang(value: string): value is Lang {\r\n return SUPPORTED_LANGS.includes(value as Lang);\r\n}\r\n","export const INPUT_TYPES = [\r\n 'text',\r\n 'password',\r\n 'email',\r\n 'search',\r\n 'tel',\r\n 'url',\r\n 'number',\r\n 'textarea',\r\n] as const;\r\n\r\nexport type InputType = (typeof INPUT_TYPES)[number];\r\n","export interface DBStoreIndex {\r\n name: string;\r\n keyPath: string;\r\n unique: boolean;\r\n}\r\n\r\nexport interface DBStore {\r\n name: string;\r\n keyPath: string;\r\n autoIncrement: boolean;\r\n indexes: DBStoreIndex[];\r\n}\r\n\r\nexport interface DBSchema {\r\n name: string;\r\n version: number;\r\n stores: DBStore[];\r\n}\r\n\r\nexport const DB_SCHEMA: DBSchema = {\r\n name: 'E2ECypressDB',\r\n version: 10,\r\n stores: [\r\n {\r\n name: 'tests',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'name', keyPath: 'name', unique: false },\r\n { name: 'createdAt', keyPath: 'createdAt', unique: false },\r\n ],\r\n },\r\n {\r\n name: 'commands',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'command', keyPath: 'command', unique: false },\r\n { name: 'testId', keyPath: 'testId', unique: false },\r\n { name: 'createdAt', keyPath: 'createdAt', unique: false },\r\n ],\r\n },\r\n {\r\n name: 'interceptors',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'interceptor', keyPath: 'interceptor', unique: false },\r\n { name: 'testId', keyPath: 'testId', unique: false },\r\n { name: 'createdAt', keyPath: 'createdAt', unique: false },\r\n ],\r\n },\r\n {\r\n name: 'configuration',\r\n keyPath: 'id',\r\n autoIncrement: true,\r\n indexes: [\r\n { name: 'language', keyPath: 'language', unique: false },\r\n { name: 'extendedHttpCommands', keyPath: 'extendedHttpCommands', unique: false },\r\n { name: 'allowReadWriteFiles', keyPath: 'allowReadWriteFiles', unique: false },\r\n ],\r\n },\r\n ],\r\n};\r\n\r\nexport const DB_STORE_NAMES = DB_SCHEMA.stores.map(s => s.name) as [\r\n 'tests',\r\n 'commands',\r\n 'interceptors',\r\n 'configuration',\r\n];\r\n","export const I18N_ES = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Configuración',\r\n SHOW_ADVANCED_EDITOR: 'Editor avanzado',\r\n DIALOG_SAVED_TESTS: 'Pruebas guardadas',\r\n DIALOG_COMMANDS: 'Previsualizador de comandos Cypress',\r\n DIALOG_SAVE: '¿Guardar la grabación?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Descripción de la prueba',\r\n CANCEL: 'Cancelar',\r\n ASK: '¿Guardar el test grabado?',\r\n YES_CONTINUE: 'Sí, continuar',\r\n NO_DISCARD: 'No, descartar',\r\n DESC_PLACEHOLDER: 'Ej: Login correcto con credenciales válidas',\r\n TAGS_LABEL: 'Etiquetas (opcional, para filtrar después):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regresión…',\r\n ADD_TAG: '+ Añadir',\r\n NO_TAGS: 'Sin etiquetas',\r\n SAVE_BTN: '💾 Guardar',\r\n SAVE_AND_EDIT: '📝 Guardar y editar',\r\n REMOVE_TAG_TITLE: 'Quitar',\r\n NOTES_LABEL: 'Descripción / Notas (opcional):',\r\n NOTES_PLACEHOLDER: 'Qué valida este test, condiciones previas, etc.',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Sin etiquetas',\r\n SELECTED_SINGULAR: 'seleccionado',\r\n SELECTED_PLURAL: 'seleccionados',\r\n DESCRIBE_PLACEHOLDER: 'Nombre del describe (opcional)',\r\n COPY_DESCRIBE: '🗂 Copiar describe()',\r\n MULTI_SELECT: '🗂 Multi-select',\r\n CANCEL_SELECT: '✕ Cancelar',\r\n SECTION_COMMANDS: 'Comandos',\r\n SECTION_INTERCEPTORS: 'Interceptores',\r\n COPY_CMDS_BTN: '📋 Copiar comandos',\r\n COPY_ICPS_BTN: '📋 Copiar interceptores',\r\n DEFAULT_DESCRIBE: 'Suite de tests',\r\n NO_TESTS: 'No hay tests guardados',\r\n DELETE_TITLE: 'Eliminar',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Idioma',\r\n LANG_FIELD: 'Interfaz',\r\n HTTP_SECTION: '⚡ HTTP Avanzado',\r\n HTTP_TITLE: 'Validaciones de body',\r\n HTTP_SUB: 'GET → response · POST/PUT → request',\r\n SELECTOR_SECTION: '🎯 Estrategia de selector',\r\n SELECTOR_LABEL: 'Atributo preferido para cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (por defecto)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#elemento)',\r\n SELECTOR_HINT: 'El grabador buscará este atributo primero. Si no existe, intentará los demás.',\r\n FOLDER_SECTION: '📁 Carpeta Cypress',\r\n FOLDER_CONNECTED: 'conectado —',\r\n FOLDER_NOT_SET: 'sin configurar',\r\n FOLDER_CHANGE_BTN: '📁 Cambiar carpeta',\r\n FOLDER_SELECT_BTN: '📁 Seleccionar carpeta',\r\n FOLDER_REVOKE_BTN: '✕ Quitar acceso',\r\n DATA_SECTION: '💾 Datos',\r\n DATA_DESC: 'Exporta todos tus tests a JSON o importa una copia de seguridad.',\r\n EXPORT_BTN: '⬆️ Exportar tests',\r\n IMPORT_BTN: '⬇️ Importar tests',\r\n FOLDER_UPDATED_TOAST: '✓ Carpeta de Cypress actualizada',\r\n FOLDER_ERROR_TOAST: 'Error al acceder a la carpeta',\r\n IMPORT_SUCCESS: 'Datos importados correctamente.',\r\n IMPORT_ERROR: 'Error al importar.',\r\n JSON_INVALID: 'El archivo no es un JSON válido.',\r\n JSON_BAD_FORMAT: 'El archivo no tiene el formato esperado.',\r\n SMART_SELECTOR_SECTION: '🔍 Selector inteligente',\r\n SMART_SELECTOR_TITLE: 'Selector inteligente',\r\n SMART_SELECTOR_SUB: 'Muestra un picker al hacer click en elementos sin selector válido.',\r\n START_HIDDEN_SECTION: '👁 Visibilidad del widget',\r\n START_HIDDEN_TITLE: 'Iniciar oculto',\r\n START_HIDDEN_SUB: 'El widget arranca invisible. Usa Ctrl+Shift+E para mostrarlo u ocultarlo.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Selecciona un elemento del DOM',\r\n PREVIEW_LABEL: 'navegar',\r\n CONFIRM_HINT: 'confirmar',\r\n CANCEL_HINT: 'cancelar',\r\n QUALITY_EXCELLENT: 'Excelente — tiene atributo de prueba (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Bueno — tiene un id válido',\r\n QUALITY_ACCEPTABLE: 'Aceptable — solo tiene clases CSS',\r\n QUALITY_POOR: 'No recomendado — solo tag o estilo inline',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptores',\r\n COPY_CMDS_BTN: '📋 Copiar comandos',\r\n SHOW_INTERCEPTORS: '▼ Ver interceptores',\r\n HIDE_INTERCEPTORS: '▲ Ocultar interceptores',\r\n SECTION_COMMANDS: 'Comandos',\r\n NO_CMDS_YET: 'Sin comandos aún',\r\n NO_ICP_SHORT: 'Sin interceptores',\r\n COPY_ICP_BTN: '📋 Copiar interceptores',\r\n UP_TITLE: 'Subir',\r\n DOWN_TITLE: 'Bajar',\r\n DEL_TITLE: 'Eliminar',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Reactivar acceso',\r\n PERMISSION_EXPIRED: '🔑 El permiso ha caducado',\r\n PERMISSION_EXPIRED_HINT: 'Haz clic para reactivar el acceso a tu carpeta de Cypress.',\r\n NO_ACCESS: '🔒 Sin acceso a archivos locales',\r\n NO_ACCESS_HINT: 'Configura el acceso en ⚙️ Config.',\r\n NO_FILES: 'Sin archivos',\r\n SELECT_FILE: '← Selecciona un archivo del árbol',\r\n IT_LABEL: '🧪 it() a insertar:',\r\n COPY_IT_BTN: '📋 Copiar it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() interceptores:',\r\n COPY_ICP_BTN: '📋 Copiar interceptores',\r\n INSERT_BTN: '💾 Insertar en archivo',\r\n EDIT_MANUAL_BTN: '✏️ Editar manualmente',\r\n CLOSE_BTN: '✕ Cerrar',\r\n NEW_FILE_BTN: '+ Nuevo archivo',\r\n REFRESH_BTN: '↻ Actualizar',\r\n NEW_FILE_PLACEHOLDER: 'nombre-del-test',\r\n NEW_FILE_CONFIRM: 'Crear',\r\n NEW_FILE_CANCEL: 'Cancelar',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Sin archivo',\r\n COPY_TITLE: 'Copiar contenido del editor',\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copiar',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: 'Sin cambios respecto al original',\r\n NO_CHANGES_SHORT: 'Sin cambios',\r\n LAUNCH_BTN: '▶ Lanzar test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Guardar',\r\n CLOSE_BTN: '✕ Cerrar',\r\n BACK_TO_EDITOR: '← Volver al editor',\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Acceso a ficheros',\r\n FS_LATER_BTN: 'Ahora no',\r\n FS_SELECT_BTN: '📁 Seleccionar carpeta',\r\n FS_SUCCESS_TOAST: '✓ Carpeta de Cypress configurada',\r\n FS_ERROR_TOAST: 'Error al acceder a la carpeta',\r\n FS_INTRO_HTML: 'El <strong style=\"color:#e6edf3\">editor avanzado</strong> puede insertar tus tests directamente en los archivos <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> de Cypress.',\r\n FS_STRUCTURE_HINT_HTML: 'Selecciona la carpeta que contiene la subcarpeta <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code>. La extensión espera esta estructura:',\r\n FS_TREE_PICK_HINT: '← selecciona esta carpeta',\r\n FS_TREE_READ_HINT: '← la extensión leerá aquí',\r\n FS_PERMISSION_NOTE: 'El permiso se guarda en el navegador y no se vuelve a solicitar.',\r\n ASSERTION_SECTION: '➕ Añadir aserción',\r\n ASSERT_SELECTOR_PH: 'selector, ej: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'valor esperado',\r\n ASSERT_ADD_BTN: '➕ Añadir',\r\n FILE_EDITOR_TITLE: '✏️ Editor de archivo',\r\n FILE_SAVED_TOAST: '✓ Archivo guardado',\r\n FILE_SAVE_ERROR_TOAST: 'Error al guardar el archivo',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Ficheros',\r\n BTN_COMMANDS: 'Comandos',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pausar (Ctrl+P)',\r\n RESUME_TITLE: 'Reanudar (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSA',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Detener (Ctrl+R)',\r\n START_TITLE: 'Grabar (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_EN = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Settings',\r\n SHOW_ADVANCED_EDITOR: 'Advanced editor',\r\n DIALOG_SAVED_TESTS: 'Saved tests',\r\n DIALOG_COMMANDS: 'Cypress commands previewer',\r\n DIALOG_SAVE: 'Save recording?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Test description',\r\n CANCEL: 'Cancel',\r\n ASK: 'Save the recorded test?',\r\n YES_CONTINUE: 'Yes, continue',\r\n NO_DISCARD: 'No, discard',\r\n DESC_PLACEHOLDER: 'E.g.: Successful login with valid credentials',\r\n TAGS_LABEL: 'Tags (optional, for later filtering):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regression…',\r\n ADD_TAG: '+ Add',\r\n NO_TAGS: 'No tags',\r\n SAVE_BTN: '💾 Save',\r\n SAVE_AND_EDIT: '📝 Save and edit',\r\n REMOVE_TAG_TITLE: 'Remove',\r\n NOTES_LABEL: 'Description / Notes (optional):',\r\n NOTES_PLACEHOLDER: 'What this test validates, preconditions, etc.',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'No tags',\r\n SELECTED_SINGULAR: 'selected',\r\n SELECTED_PLURAL: 'selected',\r\n DESCRIBE_PLACEHOLDER: 'describe name (optional)',\r\n COPY_DESCRIBE: '🗂 Copy describe()',\r\n MULTI_SELECT: '🗂 Multi-select',\r\n CANCEL_SELECT: '✕ Cancel',\r\n SECTION_COMMANDS: 'Commands',\r\n SECTION_INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Copy commands',\r\n COPY_ICPS_BTN: '📋 Copy interceptors',\r\n DEFAULT_DESCRIBE: 'Test suite',\r\n NO_TESTS: 'No saved tests',\r\n DELETE_TITLE: 'Delete',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Language',\r\n LANG_FIELD: 'Interface',\r\n HTTP_SECTION: '⚡ Advanced HTTP',\r\n HTTP_TITLE: 'Body validations',\r\n HTTP_SUB: 'GET → response · POST/PUT → request',\r\n SELECTOR_SECTION: '🎯 Selector strategy',\r\n SELECTOR_LABEL: 'Preferred attribute for cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (default)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#element)',\r\n SELECTOR_HINT: 'The recorder will look for this attribute first. If not found, it will try the others.',\r\n FOLDER_SECTION: '📁 Cypress Folder',\r\n FOLDER_CONNECTED: 'connected —',\r\n FOLDER_NOT_SET: 'not configured',\r\n FOLDER_CHANGE_BTN: '📁 Change folder',\r\n FOLDER_SELECT_BTN: '📁 Select folder',\r\n FOLDER_REVOKE_BTN: '✕ Revoke access',\r\n DATA_SECTION: '💾 Data',\r\n DATA_DESC: 'Export all your tests to JSON or import a backup.',\r\n EXPORT_BTN: '⬆️ Export tests',\r\n IMPORT_BTN: '⬇️ Import tests',\r\n FOLDER_UPDATED_TOAST: '✓ Cypress folder updated',\r\n FOLDER_ERROR_TOAST: 'Error accessing the folder',\r\n IMPORT_SUCCESS: 'Data imported successfully.',\r\n IMPORT_ERROR: 'Error importing.',\r\n JSON_INVALID: 'The file is not valid JSON.',\r\n JSON_BAD_FORMAT: 'The file does not have the expected format.',\r\n SMART_SELECTOR_SECTION: '🔍 Smart selector',\r\n SMART_SELECTOR_TITLE: 'Smart selector',\r\n SMART_SELECTOR_SUB: 'Shows a picker when clicking elements with no valid selector.',\r\n START_HIDDEN_SECTION: '👁 Widget visibility',\r\n START_HIDDEN_TITLE: 'Start hidden',\r\n START_HIDDEN_SUB: 'The widget starts invisible. Use Ctrl+Shift+E to show or hide it.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Select a DOM element',\r\n PREVIEW_LABEL: 'navigate',\r\n CONFIRM_HINT: 'confirm',\r\n CANCEL_HINT: 'cancel',\r\n QUALITY_EXCELLENT: 'Excellent — has a testing attribute (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Good — has a valid id',\r\n QUALITY_ACCEPTABLE: 'Acceptable — CSS classes only',\r\n QUALITY_POOR: 'Not recommended — tag name or inline style only',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Copy commands',\r\n SHOW_INTERCEPTORS: '▼ Show interceptors',\r\n HIDE_INTERCEPTORS: '▲ Hide interceptors',\r\n SECTION_COMMANDS: 'Commands',\r\n NO_CMDS_YET: 'No commands yet',\r\n NO_ICP_SHORT: 'No interceptors',\r\n COPY_ICP_BTN: '📋 Copy interceptors',\r\n UP_TITLE: 'Move up',\r\n DOWN_TITLE: 'Move down',\r\n DEL_TITLE: 'Delete',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Reactivate access',\r\n PERMISSION_EXPIRED: '🔑 Permission expired',\r\n PERMISSION_EXPIRED_HINT: 'Click to reactivate access to your Cypress folder.',\r\n NO_ACCESS: '🔒 No access to local files',\r\n NO_ACCESS_HINT: 'Configure access in ⚙️ Config.',\r\n NO_FILES: 'No files',\r\n SELECT_FILE: '← Select a file from the tree',\r\n IT_LABEL: '🧪 it() to insert:',\r\n COPY_IT_BTN: '📋 Copy it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() interceptors:',\r\n COPY_ICP_BTN: '📋 Copy interceptors',\r\n INSERT_BTN: '💾 Insert into file',\r\n EDIT_MANUAL_BTN: '✏️ Edit manually',\r\n CLOSE_BTN: '✕ Close',\r\n NEW_FILE_BTN: '+ New file',\r\n REFRESH_BTN: '↻ Refresh',\r\n NEW_FILE_PLACEHOLDER: 'test-name',\r\n NEW_FILE_CONFIRM: 'Create',\r\n NEW_FILE_CANCEL: 'Cancel',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'No file',\r\n COPY_TITLE: 'Copy editor content',\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copy',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: 'No changes from original',\r\n NO_CHANGES_SHORT: 'No changes',\r\n LAUNCH_BTN: '▶ Run test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Save',\r\n CLOSE_BTN: '✕ Close',\r\n BACK_TO_EDITOR: '← Back to editor',\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 File access',\r\n FS_LATER_BTN: 'Not now',\r\n FS_SELECT_BTN: '📁 Select folder',\r\n FS_SUCCESS_TOAST: '✓ Cypress folder configured',\r\n FS_ERROR_TOAST: 'Error accessing the folder',\r\n FS_INTRO_HTML: 'The <strong style=\"color:#e6edf3\">advanced editor</strong> can insert your tests directly into the Cypress <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> files.',\r\n FS_STRUCTURE_HINT_HTML: 'Select the folder that contains the <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code> subfolder. The extension expects this structure:',\r\n FS_TREE_PICK_HINT: '← select this folder',\r\n FS_TREE_READ_HINT: '← the extension will read here',\r\n FS_PERMISSION_NOTE: 'The permission is stored in the browser and will not be requested again.',\r\n ASSERTION_SECTION: '➕ Add assertion',\r\n ASSERT_SELECTOR_PH: 'selector, e.g.: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'expected value',\r\n ASSERT_ADD_BTN: '➕ Add',\r\n FILE_EDITOR_TITLE: '✏️ File editor',\r\n FILE_SAVED_TOAST: '✓ File saved',\r\n FILE_SAVE_ERROR_TOAST: 'Error saving the file',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Files',\r\n BTN_COMMANDS: 'Commands',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pause (Ctrl+P)',\r\n RESUME_TITLE: 'Resume (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSED',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Stop (Ctrl+R)',\r\n START_TITLE: 'Record (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_FR = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Paramètres',\r\n SHOW_ADVANCED_EDITOR: 'Éditeur avancé',\r\n DIALOG_SAVED_TESTS: 'Tests enregistrés',\r\n DIALOG_COMMANDS: 'Aperçu des commandes Cypress',\r\n DIALOG_SAVE: \"Enregistrer l'enregistrement ?\",\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Description du test',\r\n CANCEL: 'Annuler',\r\n ASK: 'Enregistrer le test ?',\r\n YES_CONTINUE: 'Oui, continuer',\r\n NO_DISCARD: 'Non, ignorer',\r\n DESC_PLACEHOLDER: 'Ex : Connexion réussie avec identifiants valides',\r\n TAGS_LABEL: 'Étiquettes (optionnel, pour filtrer ensuite) :',\r\n TAGS_PLACEHOLDER: 'smoke, login, régression…',\r\n ADD_TAG: '+ Ajouter',\r\n NO_TAGS: 'Sans étiquettes',\r\n SAVE_BTN: '💾 Enregistrer',\r\n SAVE_AND_EDIT: '📝 Enregistrer et éditer',\r\n REMOVE_TAG_TITLE: 'Retirer',\r\n NOTES_LABEL: 'Description / Notes (optionnel) :',\r\n NOTES_PLACEHOLDER: 'Ce que ce test valide, conditions préalables, etc.',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Sans étiquettes',\r\n SELECTED_SINGULAR: 'sélectionné',\r\n SELECTED_PLURAL: 'sélectionnés',\r\n DESCRIBE_PLACEHOLDER: 'Nom du describe (optionnel)',\r\n COPY_DESCRIBE: '🗂 Copier describe()',\r\n MULTI_SELECT: '🗂 Multi-sélection',\r\n CANCEL_SELECT: '✕ Annuler',\r\n SECTION_COMMANDS: 'Commandes',\r\n SECTION_INTERCEPTORS: 'Intercepteurs',\r\n COPY_CMDS_BTN: '📋 Copier les commandes',\r\n COPY_ICPS_BTN: '📋 Copier les intercepteurs',\r\n DEFAULT_DESCRIBE: 'Suite de tests',\r\n NO_TESTS: 'Aucun test enregistré',\r\n DELETE_TITLE: 'Supprimer',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Langue',\r\n LANG_FIELD: 'Interface',\r\n HTTP_SECTION: '⚡ HTTP Avancé',\r\n HTTP_TITLE: 'Validations du corps',\r\n HTTP_SUB: 'GET → réponse · POST/PUT → requête',\r\n SELECTOR_SECTION: '🎯 Stratégie de sélecteur',\r\n SELECTOR_LABEL: 'Attribut préféré pour cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (par défaut)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#élément)',\r\n SELECTOR_HINT: \"L'enregistreur cherchera d'abord cet attribut. Si absent, il essaiera les autres.\",\r\n FOLDER_SECTION: '📁 Dossier Cypress',\r\n FOLDER_CONNECTED: 'connecté —',\r\n FOLDER_NOT_SET: 'non configuré',\r\n FOLDER_CHANGE_BTN: '📁 Changer de dossier',\r\n FOLDER_SELECT_BTN: '📁 Sélectionner un dossier',\r\n FOLDER_REVOKE_BTN: \"✕ Révoquer l'accès\",\r\n DATA_SECTION: '💾 Données',\r\n DATA_DESC: 'Exportez tous vos tests en JSON ou importez une sauvegarde.',\r\n EXPORT_BTN: '⬆️ Exporter les tests',\r\n IMPORT_BTN: '⬇️ Importer les tests',\r\n FOLDER_UPDATED_TOAST: '✓ Dossier Cypress mis à jour',\r\n FOLDER_ERROR_TOAST: \"Erreur lors de l'accès au dossier\",\r\n IMPORT_SUCCESS: 'Données importées avec succès.',\r\n IMPORT_ERROR: \"Erreur lors de l'importation.\",\r\n JSON_INVALID: \"Le fichier n'est pas un JSON valide.\",\r\n JSON_BAD_FORMAT: \"Le fichier n'a pas le format attendu.\",\r\n SMART_SELECTOR_SECTION: '🔍 Sélecteur intelligent',\r\n SMART_SELECTOR_TITLE: 'Sélecteur intelligent',\r\n SMART_SELECTOR_SUB: 'Affiche un sélecteur lors du clic sur des éléments sans sélecteur valide.',\r\n START_HIDDEN_SECTION: '👁 Visibilité du widget',\r\n START_HIDDEN_TITLE: 'Démarrer masqué',\r\n START_HIDDEN_SUB: 'Le widget démarre invisible. Utilisez Ctrl+Shift+E pour l\\'afficher ou le masquer.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Sélectionnez un élément du DOM',\r\n PREVIEW_LABEL: 'naviguer',\r\n CONFIRM_HINT: 'confirmer',\r\n CANCEL_HINT: 'annuler',\r\n QUALITY_EXCELLENT: 'Excellent — attribut de test présent (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Bon — id valide',\r\n QUALITY_ACCEPTABLE: 'Acceptable — classes CSS uniquement',\r\n QUALITY_POOR: 'Déconseillé — seulement le nom de balise ou style inline',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Intercepteurs',\r\n COPY_CMDS_BTN: '📋 Copier les commandes',\r\n SHOW_INTERCEPTORS: '▼ Voir les intercepteurs',\r\n HIDE_INTERCEPTORS: '▲ Masquer les intercepteurs',\r\n SECTION_COMMANDS: 'Commandes',\r\n NO_CMDS_YET: 'Aucune commande encore',\r\n NO_ICP_SHORT: 'Aucun intercepteur',\r\n COPY_ICP_BTN: '📋 Copier les intercepteurs',\r\n UP_TITLE: 'Monter',\r\n DOWN_TITLE: 'Descendre',\r\n DEL_TITLE: 'Supprimer',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: \"🔓 Réactiver l'accès\",\r\n PERMISSION_EXPIRED: '🔑 Autorisation expirée',\r\n PERMISSION_EXPIRED_HINT: \"Cliquez pour réactiver l'accès à votre dossier Cypress.\",\r\n NO_ACCESS: '🔒 Pas d\\'accès aux fichiers locaux',\r\n NO_ACCESS_HINT: \"Configurez l'accès dans ⚙️ Config.\",\r\n NO_FILES: 'Aucun fichier',\r\n SELECT_FILE: \"← Sélectionnez un fichier dans l'arborescence\",\r\n IT_LABEL: '🧪 it() à insérer :',\r\n COPY_IT_BTN: '📋 Copier it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() intercepteurs :',\r\n COPY_ICP_BTN: '📋 Copier les intercepteurs',\r\n INSERT_BTN: '💾 Insérer dans le fichier',\r\n EDIT_MANUAL_BTN: '✏️ Éditer manuellement',\r\n CLOSE_BTN: '✕ Fermer',\r\n NEW_FILE_BTN: '+ Nouveau fichier',\r\n REFRESH_BTN: '↻ Actualiser',\r\n NEW_FILE_PLACEHOLDER: 'nom-du-test',\r\n NEW_FILE_CONFIRM: 'Créer',\r\n NEW_FILE_CANCEL: 'Annuler',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Sans fichier',\r\n COPY_TITLE: \"Copier le contenu de l'éditeur\",\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copier',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: \"Aucun changement par rapport à l'original\",\r\n NO_CHANGES_SHORT: 'Aucun changement',\r\n LAUNCH_BTN: '▶ Lancer le test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Enregistrer',\r\n CLOSE_BTN: '✕ Fermer',\r\n BACK_TO_EDITOR: \"← Retour à l'éditeur\",\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Accès aux fichiers',\r\n FS_LATER_BTN: 'Pas maintenant',\r\n FS_SELECT_BTN: '📁 Sélectionner un dossier',\r\n FS_SUCCESS_TOAST: '✓ Dossier Cypress configuré',\r\n FS_ERROR_TOAST: \"Erreur lors de l'accès au dossier\",\r\n FS_INTRO_HTML: 'L\\'<strong style=\"color:#e6edf3\">éditeur avancé</strong> peut insérer vos tests directement dans les fichiers <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> de Cypress.',\r\n FS_STRUCTURE_HINT_HTML: 'Sélectionnez le dossier qui contient le sous-dossier <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code>. L\\'extension attend cette structure :',\r\n FS_TREE_PICK_HINT: '← sélectionnez ce dossier',\r\n FS_TREE_READ_HINT: '← l\\'extension lira ici',\r\n FS_PERMISSION_NOTE: 'L\\'autorisation est enregistrée dans le navigateur et ne sera plus demandée.',\r\n ASSERTION_SECTION: '➕ Ajouter une assertion',\r\n ASSERT_SELECTOR_PH: 'sélecteur, ex : [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'valeur attendue',\r\n ASSERT_ADD_BTN: '➕ Ajouter',\r\n FILE_EDITOR_TITLE: '✏️ Éditeur de fichier',\r\n FILE_SAVED_TOAST: '✓ Fichier enregistré',\r\n FILE_SAVE_ERROR_TOAST: \"Erreur lors de l'enregistrement\",\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Fichiers',\r\n BTN_COMMANDS: 'Commandes',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pause (Ctrl+P)',\r\n RESUME_TITLE: 'Reprendre (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSE',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Arrêter (Ctrl+R)',\r\n START_TITLE: 'Enregistrer (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_IT = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Impostazioni',\r\n SHOW_ADVANCED_EDITOR: 'Editor avanzato',\r\n DIALOG_SAVED_TESTS: 'Test salvati',\r\n DIALOG_COMMANDS: 'Anteprima comandi Cypress',\r\n DIALOG_SAVE: 'Salvare la registrazione?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Descrizione del test',\r\n CANCEL: 'Annulla',\r\n ASK: 'Salvare il test registrato?',\r\n YES_CONTINUE: 'Sì, continua',\r\n NO_DISCARD: 'No, annulla',\r\n DESC_PLACEHOLDER: 'Es: Login riuscito con credenziali valide',\r\n TAGS_LABEL: 'Etichette (opzionale, per filtrare dopo):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regressione…',\r\n ADD_TAG: '+ Aggiungi',\r\n NO_TAGS: 'Nessuna etichetta',\r\n SAVE_BTN: '💾 Salva',\r\n SAVE_AND_EDIT: '📝 Salva e modifica',\r\n REMOVE_TAG_TITLE: 'Rimuovi',\r\n NOTES_LABEL: 'Descrizione / Note (opzionale):',\r\n NOTES_PLACEHOLDER: 'Cosa valida questo test, condizioni preliminari, ecc.',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Nessuna etichetta',\r\n SELECTED_SINGULAR: 'selezionato',\r\n SELECTED_PLURAL: 'selezionati',\r\n DESCRIBE_PLACEHOLDER: 'Nome del describe (opzionale)',\r\n COPY_DESCRIBE: '🗂 Copia describe()',\r\n MULTI_SELECT: '🗂 Multi-selezione',\r\n CANCEL_SELECT: '✕ Annulla',\r\n SECTION_COMMANDS: 'Comandi',\r\n SECTION_INTERCEPTORS: 'Interceptor',\r\n COPY_CMDS_BTN: '📋 Copia comandi',\r\n COPY_ICPS_BTN: '📋 Copia interceptor',\r\n DEFAULT_DESCRIBE: 'Suite di test',\r\n NO_TESTS: 'Nessun test salvato',\r\n DELETE_TITLE: 'Elimina',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Lingua',\r\n LANG_FIELD: 'Interfaccia',\r\n HTTP_SECTION: '⚡ HTTP Avanzato',\r\n HTTP_TITLE: 'Validazioni del body',\r\n HTTP_SUB: 'GET → risposta · POST/PUT → richiesta',\r\n SELECTOR_SECTION: '🎯 Strategia selettore',\r\n SELECTOR_LABEL: 'Attributo preferito per cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (predefinito)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#elemento)',\r\n SELECTOR_HINT: \"Il registratore cercherà prima questo attributo. Se assente, proverà gli altri.\",\r\n FOLDER_SECTION: '📁 Cartella Cypress',\r\n FOLDER_CONNECTED: 'connesso —',\r\n FOLDER_NOT_SET: 'non configurato',\r\n FOLDER_CHANGE_BTN: '📁 Cambia cartella',\r\n FOLDER_SELECT_BTN: '📁 Seleziona cartella',\r\n FOLDER_REVOKE_BTN: '✕ Revoca accesso',\r\n DATA_SECTION: '💾 Dati',\r\n DATA_DESC: 'Esporta tutti i tuoi test in JSON o importa un backup.',\r\n EXPORT_BTN: '⬆️ Esporta test',\r\n IMPORT_BTN: '⬇️ Importa test',\r\n FOLDER_UPDATED_TOAST: '✓ Cartella Cypress aggiornata',\r\n FOLDER_ERROR_TOAST: \"Errore durante l'accesso alla cartella\",\r\n IMPORT_SUCCESS: 'Dati importati correttamente.',\r\n IMPORT_ERROR: \"Errore durante l'importazione.\",\r\n JSON_INVALID: 'Il file non è un JSON valido.',\r\n JSON_BAD_FORMAT: 'Il file non ha il formato previsto.',\r\n SMART_SELECTOR_SECTION: '🔍 Selettore intelligente',\r\n SMART_SELECTOR_TITLE: 'Selettore intelligente',\r\n SMART_SELECTOR_SUB: 'Mostra un selettore quando si fa clic su elementi senza selettore valido.',\r\n START_HIDDEN_SECTION: '👁 Visibilità del widget',\r\n START_HIDDEN_TITLE: 'Avvia nascosto',\r\n START_HIDDEN_SUB: 'Il widget si avvia invisibile. Usa Ctrl+Shift+E per mostrarlo o nasconderlo.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'Seleziona un elemento DOM',\r\n PREVIEW_LABEL: 'navigare',\r\n CONFIRM_HINT: 'confermare',\r\n CANCEL_HINT: 'annullare',\r\n QUALITY_EXCELLENT: 'Eccellente — attributo di test presente (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Buono — id valido',\r\n QUALITY_ACCEPTABLE: 'Accettabile — solo classi CSS',\r\n QUALITY_POOR: 'Sconsigliato — solo tag o stile inline',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptor',\r\n COPY_CMDS_BTN: '📋 Copia comandi',\r\n SHOW_INTERCEPTORS: '▼ Vedi interceptor',\r\n HIDE_INTERCEPTORS: '▲ Nascondi interceptor',\r\n SECTION_COMMANDS: 'Comandi',\r\n NO_CMDS_YET: 'Ancora nessun comando',\r\n NO_ICP_SHORT: 'Nessun interceptor',\r\n COPY_ICP_BTN: '📋 Copia interceptor',\r\n UP_TITLE: 'Su',\r\n DOWN_TITLE: 'Giù',\r\n DEL_TITLE: 'Elimina',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Riattiva accesso',\r\n PERMISSION_EXPIRED: '🔑 Autorizzazione scaduta',\r\n PERMISSION_EXPIRED_HINT: \"Clicca per riattivare l'accesso alla cartella Cypress.\",\r\n NO_ACCESS: '🔒 Nessun accesso ai file locali',\r\n NO_ACCESS_HINT: \"Configura l'accesso in ⚙️ Config.\",\r\n NO_FILES: 'Nessun file',\r\n SELECT_FILE: \"← Seleziona un file dall'albero\",\r\n IT_LABEL: '🧪 it() da inserire:',\r\n COPY_IT_BTN: '📋 Copia it()',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() interceptor:',\r\n COPY_ICP_BTN: '📋 Copia interceptor',\r\n INSERT_BTN: '💾 Inserisci nel file',\r\n EDIT_MANUAL_BTN: '✏️ Modifica manualmente',\r\n CLOSE_BTN: '✕ Chiudi',\r\n NEW_FILE_BTN: '+ Nuovo file',\r\n REFRESH_BTN: '↻ Aggiorna',\r\n NEW_FILE_PLACEHOLDER: 'nome-del-test',\r\n NEW_FILE_CONFIRM: 'Crea',\r\n NEW_FILE_CANCEL: 'Annulla',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Nessun file',\r\n COPY_TITLE: \"Copia il contenuto dell'editor\",\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Copia',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: \"Nessuna modifica rispetto all'originale\",\r\n NO_CHANGES_SHORT: 'Nessuna modifica',\r\n LAUNCH_BTN: '▶ Esegui test',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Salva',\r\n CLOSE_BTN: '✕ Chiudi',\r\n BACK_TO_EDITOR: \"← Torna all'editor\",\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Accesso ai file',\r\n FS_LATER_BTN: 'Non ora',\r\n FS_SELECT_BTN: '📁 Seleziona cartella',\r\n FS_SUCCESS_TOAST: '✓ Cartella Cypress configurata',\r\n FS_ERROR_TOAST: \"Errore durante l'accesso alla cartella\",\r\n FS_INTRO_HTML: 'L\\'<strong style=\"color:#e6edf3\">editor avanzato</strong> può inserire i tuoi test direttamente nei file <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> di Cypress.',\r\n FS_STRUCTURE_HINT_HTML: 'Seleziona la cartella che contiene la sottocartella <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code>. L\\'estensione si aspetta questa struttura:',\r\n FS_TREE_PICK_HINT: '← seleziona questa cartella',\r\n FS_TREE_READ_HINT: '← l\\'estensione leggerà qui',\r\n FS_PERMISSION_NOTE: 'Il permesso viene salvato nel browser e non sarà richiesto di nuovo.',\r\n ASSERTION_SECTION: '➕ Aggiungi asserzione',\r\n ASSERT_SELECTOR_PH: 'selettore, es: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'valore atteso',\r\n ASSERT_ADD_BTN: '➕ Aggiungi',\r\n FILE_EDITOR_TITLE: '✏️ Editor di file',\r\n FILE_SAVED_TOAST: '✓ File salvato',\r\n FILE_SAVE_ERROR_TOAST: 'Errore durante il salvataggio',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'File',\r\n BTN_COMMANDS: 'Comandi',\r\n BTN_TESTS: 'Test',\r\n PAUSE_TITLE: 'Pausa (Ctrl+P)',\r\n RESUME_TITLE: 'Riprendi (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSA',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Ferma (Ctrl+R)',\r\n START_TITLE: 'Registra (Ctrl+R)',\r\n },\r\n};\r\n","export const I18N_DE = {\r\n MAIN_FRAME: {\r\n SETTINGS: 'Einstellungen',\r\n SHOW_ADVANCED_EDITOR: 'Erweiterter Editor',\r\n DIALOG_SAVED_TESTS: 'Gespeicherte Tests',\r\n DIALOG_COMMANDS: 'Cypress-Befehle Vorschau',\r\n DIALOG_SAVE: 'Aufzeichnung speichern?',\r\n },\r\n SAVE_TEST: {\r\n DESC_LABEL: 'Testbeschreibung',\r\n CANCEL: 'Abbrechen',\r\n ASK: 'Aufgezeichneten Test speichern?',\r\n YES_CONTINUE: 'Ja, weiter',\r\n NO_DISCARD: 'Nein, verwerfen',\r\n DESC_PLACEHOLDER: 'Z. B.: Erfolgreiche Anmeldung mit gültigen Zugangsdaten',\r\n TAGS_LABEL: 'Tags (optional, zum späteren Filtern):',\r\n TAGS_PLACEHOLDER: 'smoke, login, regression…',\r\n ADD_TAG: '+ Hinzufügen',\r\n NO_TAGS: 'Keine Tags',\r\n SAVE_BTN: '💾 Speichern',\r\n SAVE_AND_EDIT: '📝 Speichern und bearbeiten',\r\n REMOVE_TAG_TITLE: 'Entfernen',\r\n NOTES_LABEL: 'Beschreibung / Notizen (optional):',\r\n NOTES_PLACEHOLDER: 'Was dieser Test validiert, Voraussetzungen usw.',\r\n },\r\n TEST_EDITOR: {\r\n NO_TAGS: 'Keine Tags',\r\n SELECTED_SINGULAR: 'ausgewählt',\r\n SELECTED_PLURAL: 'ausgewählt',\r\n DESCRIBE_PLACEHOLDER: 'describe-Name (optional)',\r\n COPY_DESCRIBE: '🗂 describe() kopieren',\r\n MULTI_SELECT: '🗂 Mehrfachauswahl',\r\n CANCEL_SELECT: '✕ Abbrechen',\r\n SECTION_COMMANDS: 'Befehle',\r\n SECTION_INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Befehle kopieren',\r\n COPY_ICPS_BTN: '📋 Interceptors kopieren',\r\n DEFAULT_DESCRIBE: 'Test-Suite',\r\n NO_TESTS: 'Keine gespeicherten Tests',\r\n DELETE_TITLE: 'Löschen',\r\n },\r\n CONFIG: {\r\n LANG_SECTION: '🌐 Sprache',\r\n LANG_FIELD: 'Oberfläche',\r\n HTTP_SECTION: '⚡ Erweitertes HTTP',\r\n HTTP_TITLE: 'Body-Validierungen',\r\n HTTP_SUB: 'GET → Antwort · POST/PUT → Anfrage',\r\n SELECTOR_SECTION: '🎯 Selector-Strategie',\r\n SELECTOR_LABEL: 'Bevorzugtes Attribut für cy.get()',\r\n SELECTOR_OPT_DATACY: 'data-cy (Standard)',\r\n SELECTOR_OPT_TESTID: 'data-testid',\r\n SELECTOR_OPT_ARIA: 'aria-label',\r\n SELECTOR_OPT_ID: 'id (#element)',\r\n SELECTOR_HINT: 'Der Recorder sucht zuerst nach diesem Attribut. Falls nicht gefunden, versucht er die anderen.',\r\n FOLDER_SECTION: '📁 Cypress-Ordner',\r\n FOLDER_CONNECTED: 'verbunden —',\r\n FOLDER_NOT_SET: 'nicht konfiguriert',\r\n FOLDER_CHANGE_BTN: '📁 Ordner wechseln',\r\n FOLDER_SELECT_BTN: '📁 Ordner auswählen',\r\n FOLDER_REVOKE_BTN: '✕ Zugriff widerrufen',\r\n DATA_SECTION: '💾 Daten',\r\n DATA_DESC: 'Exportieren Sie alle Tests als JSON oder importieren Sie ein Backup.',\r\n EXPORT_BTN: '⬆️ Tests exportieren',\r\n IMPORT_BTN: '⬇️ Tests importieren',\r\n FOLDER_UPDATED_TOAST: '✓ Cypress-Ordner aktualisiert',\r\n FOLDER_ERROR_TOAST: 'Fehler beim Zugriff auf den Ordner',\r\n IMPORT_SUCCESS: 'Daten erfolgreich importiert.',\r\n IMPORT_ERROR: 'Fehler beim Importieren.',\r\n JSON_INVALID: 'Die Datei ist kein gültiges JSON.',\r\n JSON_BAD_FORMAT: 'Die Datei hat nicht das erwartete Format.',\r\n SMART_SELECTOR_SECTION: '🔍 Intelligenter Selektor',\r\n SMART_SELECTOR_TITLE: 'Intelligenter Selektor',\r\n SMART_SELECTOR_SUB: 'Zeigt ein Auswahlfeld, wenn auf Elemente ohne gültigen Selektor geklickt wird.',\r\n START_HIDDEN_SECTION: '👁 Widget-Sichtbarkeit',\r\n START_HIDDEN_TITLE: 'Versteckt starten',\r\n START_HIDDEN_SUB: 'Das Widget startet unsichtbar. Verwenden Sie Ctrl+Shift+E zum Ein-/Ausblenden.',\r\n },\r\n SELECTOR_PICKER: {\r\n TITLE: 'DOM-Element auswählen',\r\n PREVIEW_LABEL: 'navigieren',\r\n CONFIRM_HINT: 'bestätigen',\r\n CANCEL_HINT: 'abbrechen',\r\n QUALITY_EXCELLENT: 'Ausgezeichnet — Test-Attribut vorhanden (data-cy / data-testid / aria-label)',\r\n QUALITY_GOOD: 'Gut — gültige ID',\r\n QUALITY_ACCEPTABLE: 'Akzeptabel — nur CSS-Klassen',\r\n QUALITY_POOR: 'Nicht empfohlen — nur Tag oder Inline-Style',\r\n },\r\n TEST_PREVISUALIZER: {\r\n INTERCEPTORS: 'Interceptors',\r\n COPY_CMDS_BTN: '📋 Befehle kopieren',\r\n SHOW_INTERCEPTORS: '▼ Interceptors anzeigen',\r\n HIDE_INTERCEPTORS: '▲ Interceptors ausblenden',\r\n SECTION_COMMANDS: 'Befehle',\r\n NO_CMDS_YET: 'Noch keine Befehle',\r\n NO_ICP_SHORT: 'Keine Interceptors',\r\n COPY_ICP_BTN: '📋 Interceptors kopieren',\r\n UP_TITLE: 'Nach oben',\r\n DOWN_TITLE: 'Nach unten',\r\n DEL_TITLE: 'Löschen',\r\n },\r\n ADVANCED_EDITOR: {\r\n REAUTH_BTN: '🔓 Zugriff reaktivieren',\r\n PERMISSION_EXPIRED: '🔑 Berechtigung abgelaufen',\r\n PERMISSION_EXPIRED_HINT: 'Klicken Sie, um den Zugriff auf Ihren Cypress-Ordner zu reaktivieren.',\r\n NO_ACCESS: '🔒 Kein Zugriff auf lokale Dateien',\r\n NO_ACCESS_HINT: 'Konfigurieren Sie den Zugriff unter ⚙️ Config.',\r\n NO_FILES: 'Keine Dateien',\r\n SELECT_FILE: '← Wählen Sie eine Datei aus dem Baum',\r\n IT_LABEL: '🧪 it() zum Einfügen:',\r\n COPY_IT_BTN: '📋 it() kopieren',\r\n BEFORE_EACH_LABEL: '🔀 beforeEach() Interceptors:',\r\n COPY_ICP_BTN: '📋 Interceptors kopieren',\r\n INSERT_BTN: '💾 In Datei einfügen',\r\n EDIT_MANUAL_BTN: '✏️ Manuell bearbeiten',\r\n CLOSE_BTN: '✕ Schließen',\r\n NEW_FILE_BTN: '+ Neue Datei',\r\n REFRESH_BTN: '↻ Aktualisieren',\r\n NEW_FILE_PLACEHOLDER: 'test-name',\r\n NEW_FILE_CONFIRM: 'Erstellen',\r\n NEW_FILE_CANCEL: 'Abbrechen',\r\n },\r\n FILE_PREVIEW: {\r\n NO_FILE: 'Keine Datei',\r\n COPY_TITLE: 'Editor-Inhalt kopieren',\r\n BLOCK_IT: '🧪 it()',\r\n COPY_BTN: '📋 Kopieren',\r\n BLOCK_BEFORE_EACH: '🔀 beforeEach()',\r\n NO_CHANGES: 'Keine Änderungen gegenüber dem Original',\r\n NO_CHANGES_SHORT: 'Keine Änderungen',\r\n LAUNCH_BTN: '▶ Test starten',\r\n DIFF_BTN: '📊 Diff',\r\n SAVE_BTN: '💾 Speichern',\r\n CLOSE_BTN: '✕ Schließen',\r\n BACK_TO_EDITOR: '← Zurück zum Editor',\r\n },\r\n RECORDER: {\r\n FS_TITLE: '📁 Dateizugriff',\r\n FS_LATER_BTN: 'Nicht jetzt',\r\n FS_SELECT_BTN: '📁 Ordner auswählen',\r\n FS_SUCCESS_TOAST: '✓ Cypress-Ordner konfiguriert',\r\n FS_ERROR_TOAST: 'Fehler beim Zugriff auf den Ordner',\r\n FS_INTRO_HTML: 'Der <strong style=\"color:#e6edf3\">erweiterte Editor</strong> kann Ihre Tests direkt in die Cypress-Dateien <code style=\"background:#0d1117;padding:1px 6px;border-radius:4px;font-size:11px;color:#c9d1d9\">.cy.ts</code> einfügen.',\r\n FS_STRUCTURE_HINT_HTML: 'Wählen Sie den Ordner, der den Unterordner <code style=\"background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9\">e2e/</code> enthält. Die Erweiterung erwartet diese Struktur:',\r\n FS_TREE_PICK_HINT: '← diesen Ordner auswählen',\r\n FS_TREE_READ_HINT: '← die Erweiterung liest hier',\r\n FS_PERMISSION_NOTE: 'Die Berechtigung wird im Browser gespeichert und nicht erneut angefordert.',\r\n ASSERTION_SECTION: '➕ Assertion hinzufügen',\r\n ASSERT_SELECTOR_PH: 'Selektor, z. B.: [data-cy=\"btn\"]',\r\n ASSERT_VALUE_PH: 'erwarteter Wert',\r\n ASSERT_ADD_BTN: '➕ Hinzufügen',\r\n FILE_EDITOR_TITLE: '✏️ Datei-Editor',\r\n FILE_SAVED_TOAST: '✓ Datei gespeichert',\r\n FILE_SAVE_ERROR_TOAST: 'Fehler beim Speichern',\r\n BTN_CONFIG: 'Config',\r\n BTN_FILES: 'Dateien',\r\n BTN_COMMANDS: 'Befehle',\r\n BTN_TESTS: 'Tests',\r\n PAUSE_TITLE: 'Pausieren (Ctrl+P)',\r\n RESUME_TITLE: 'Fortsetzen (Ctrl+P)',\r\n BADGE_PAUSED: '⏸ PAUSE',\r\n BADGE_REC: '● REC',\r\n STOP_TITLE: 'Stopp (Ctrl+R)',\r\n START_TITLE: 'Aufzeichnen (Ctrl+R)',\r\n },\r\n};\r\n","import { type Lang, isLang } from '../models/lang.model';\r\nimport { I18N_ES } from '../i18n/es';\r\nimport { I18N_EN } from '../i18n/en';\r\nimport { I18N_FR } from '../i18n/fr';\r\nimport { I18N_IT } from '../i18n/it';\r\nimport { I18N_DE } from '../i18n/de';\r\n\r\ntype Translations = typeof I18N_ES;\r\n\r\nexport class TranslationService {\r\n private lang: Lang;\r\n\r\n private readonly translations: Record<Lang, Translations> = {\r\n es: I18N_ES,\r\n en: I18N_EN,\r\n fr: I18N_FR,\r\n it: I18N_IT,\r\n de: I18N_DE,\r\n };\r\n\r\n constructor() {\r\n this.lang = this.detectLang();\r\n }\r\n\r\n setLang(lang: Lang): void {\r\n this.lang = lang;\r\n }\r\n\r\n getLang(): Lang {\r\n return this.lang;\r\n }\r\n\r\n translate(key: string): string {\r\n const keys = key.split('.');\r\n let value: unknown = this.translations[this.lang];\r\n for (const k of keys) {\r\n value = (value as Record<string, unknown>)?.[k];\r\n if (value === undefined) return key;\r\n }\r\n return value as string;\r\n }\r\n\r\n detectLang(): Lang {\r\n const browserLang = navigator.language.split('-')[0];\r\n return isLang(browserLang) ? browserLang : 'es';\r\n }\r\n}\r\n\r\nexport const translationService = new TranslationService();\r\n","function gcd(a: number, b: number): number {\n while (b) { const t = b; b = a % b; a = t; }\n return a;\n}\n\n/**\n * Normalizes indentation in a code block and prefixes every line with baseIndent.\n *\n * Algorithm:\n * 1. Strip trailing whitespace from each line.\n * 2. Find the minimum leading-whitespace count of non-empty lines (dedent).\n * 3. Compute the indent step as the GCD of all non-zero relative indent values,\n * so the original indent unit (4-space, 8-space, etc.) maps to 2-space levels.\n * 4. Re-emit each line as: baseIndent + ' '.repeat(level) + trimmedContent.\n *\n * This handles multi-line interceptor/command blocks that were stored with\n * inconsistent or file-origin indentation.\n */\nexport function normalizeBlock(code: string, baseIndent: string): string {\n const lines = code.split('\\n').map(l => l.trimEnd());\n const nonEmpty = lines.filter(l => l.trim().length > 0);\n if (!nonEmpty.length) return '';\n\n const indents = nonEmpty.map(l => l.length - l.trimStart().length);\n const minIndent = Math.min(...indents);\n const relIndents = [...new Set(indents.map(n => n - minIndent).filter(n => n > 0))];\n const step = relIndents.length > 0 ? relIndents.reduce(gcd) : 2;\n\n return lines\n .map(l => {\n if (!l.trim()) return '';\n const level = Math.round((l.length - l.trimStart().length - minIndent) / step);\n return baseIndent + ' '.repeat(level) + l.trimStart();\n })\n .join('\\n');\n}\n","import { type Lang, isLang } from '../models/lang.model';\r\nimport { normalizeBlock } from '../utils/code-format.utils';\r\n\r\nexport class TransformationService {\r\n toLang(lang: string): Lang {\r\n return isLang(lang) ? lang : 'en';\r\n }\r\n\r\n generateItDescription(description: string, commands: string[]): string {\r\n const commandsBlock = commands.map((cmd) => normalizeBlock(cmd, ' ')).join('\\n');\r\n return `it('${description}', () => {\\n${commandsBlock}\\n});`;\r\n }\r\n}\r\n\r\nexport const transformationService = new TransformationService();\r\n","export interface DirectoryNode {\r\n name: string;\r\n kind: 'directory';\r\n children: (DirectoryNode | FileNode)[];\r\n}\r\n\r\nexport interface FileNode {\r\n name: string;\r\n kind: 'file';\r\n}\r\n\r\nexport class AdvancedTestTransformationService {\r\n insertBeforeEach(content: string, interceptors: string, alertFn?: (msg: string) => void): string {\r\n const match = content.match(/(describe\\s*\\(.*?{)/s);\r\n if (!match) {\r\n alertFn?.('ADVANCED_EDITOR.NO_DESCRIBE');\r\n return '';\r\n }\r\n const insertPos = (match.index ?? 0) + match[0].length;\r\n const beforeEachBlock = `\\n beforeEach(() => {\\n${interceptors} })\\n`;\r\n return content.slice(0, insertPos) + beforeEachBlock + content.slice(insertPos);\r\n }\r\n\r\n insertItBlock(content: string, itBlock: string, alertFn?: (msg: string) => void): string {\r\n const idx = content.lastIndexOf('})');\r\n if (idx === -1) {\r\n alertFn?.('ADVANCED_EDITOR.NO_END');\r\n return '';\r\n }\r\n return content.slice(0, idx) + '\\n' + itBlock + '\\n' + content.slice(idx);\r\n }\r\n\r\n buildBlockComment(notes: string): string {\r\n if (!notes.trim()) return '';\r\n const lines = notes.split('\\n').map(l => ` * ${l}`).join('\\n');\r\n return `/**\\n${lines}\\n */`;\r\n }\r\n\r\n isFile(file: unknown): boolean {\r\n return !!file && (file as FileNode).kind === 'file';\r\n }\r\n\r\n async scanDirectory(dirHandle: FileSystemDirectoryHandle): Promise<DirectoryNode> {\r\n const result: DirectoryNode = { name: dirHandle.name, kind: 'directory', children: [] };\r\n for await (const entry of dirHandle.values()) {\r\n if (entry.kind === 'directory') {\r\n result.children.push(await this.scanDirectory(entry as FileSystemDirectoryHandle));\r\n } else {\r\n result.children.push({ name: entry.name, kind: 'file' });\r\n }\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nexport const advancedTestTransformationService = new AdvancedTestTransformationService();\r\n","export class Subject<T> {\r\n private _value: T;\r\n private listeners = new Set<(v: T) => void>();\r\n\r\n constructor(initialValue: T) {\r\n this._value = initialValue;\r\n }\r\n\r\n next(value: T): void {\r\n this._value = value;\r\n this.listeners.forEach((l) => l(value));\r\n }\r\n\r\n getValue(): T {\r\n return this._value;\r\n }\r\n\r\n subscribe(fn: (v: T) => void): () => void {\r\n this.listeners.add(fn);\r\n return () => this.listeners.delete(fn);\r\n }\r\n}\r\n","import { INPUT_TYPES } from '../models/input-types.model';\r\nimport { Subject } from '../utils/subject';\r\nimport { FORBIDDEN_ID_PREFIXES } from '../utils/selector-quality.utils';\r\n\r\nconst OWN_SELECTOR = '[data-cy=\"lib-e2e-cypress-for-dummys\"]';\r\n\r\nexport type SelectorStrategy = 'data-cy' | 'data-testid' | 'aria-label' | 'id';\r\n\r\nexport class RecordingService {\r\n private readonly commands$ = new Subject<string[]>([]);\r\n private readonly interceptors$ = new Subject<string[]>([]);\r\n private readonly isRecording$ = new Subject<boolean>(false);\r\n private readonly isPaused$ = new Subject<boolean>(false);\r\n private readonly selectorNotFound$ = new Subject<{ target: HTMLElement; action: 'click' } | null>(null);\r\n private readonly inputDebounceTimers = new Map<HTMLElement, ReturnType<typeof setTimeout>>();\r\n private readonly abort = new AbortController();\r\n\r\n selectorStrategy: SelectorStrategy = 'data-cy';\r\n\r\n // Stored originals for history patching cleanup\r\n private readonly origPushState = history.pushState.bind(history);\r\n private readonly origReplaceState = history.replaceState.bind(history);\r\n\r\n constructor() {\r\n this.listenToClicks();\r\n this.listenToInput();\r\n this.listenToSelect();\r\n this.listenToRouteChanges();\r\n }\r\n\r\n // ── Public API ────────────────────────────────────────────────────────────\r\n\r\n startRecording(): void {\r\n this.isPaused$.next(false);\r\n this.isRecording$.next(true);\r\n this.addCommand(`cy.viewport(1900, 1200)`);\r\n this.addCommand(`cy.visit('${window.location.pathname}')`);\r\n this.addCommand(`cy.get('[data-cy=\"lib-e2e-cypress-for-dummys\"]').invoke('hide');`);\r\n }\r\n\r\n stopRecording(): void {\r\n this.isPaused$.next(false);\r\n this.isRecording$.next(false);\r\n }\r\n\r\n toggleRecording(): void {\r\n if (this.isRecording$.getValue()) {\r\n this.stopRecording();\r\n } else {\r\n this.startRecording();\r\n }\r\n }\r\n\r\n pauseRecording(): void {\r\n if (!this.isRecording$.getValue()) return;\r\n this.isPaused$.next(true);\r\n }\r\n\r\n resumeRecording(): void {\r\n this.isPaused$.next(false);\r\n }\r\n\r\n togglePause(): void {\r\n if (this.isPaused$.getValue()) {\r\n this.resumeRecording();\r\n } else {\r\n this.pauseRecording();\r\n }\r\n }\r\n\r\n addCommand(cmd: string): void {\r\n if (!this.isRecording$.getValue() || this.isPaused$.getValue()) return;\r\n this.commands$.next([...this.commands$.getValue(), cmd]);\r\n }\r\n\r\n /** Appends a command regardless of recording/paused state (e.g. assertions added manually). */\r\n appendCommand(cmd: string): void {\r\n this.commands$.next([...this.commands$.getValue(), cmd]);\r\n }\r\n\r\n removeCommand(index: number): void {\r\n const cmds = this.commands$.getValue();\r\n if (index < 0 || index >= cmds.length) return;\r\n this.commands$.next([...cmds.slice(0, index), ...cmds.slice(index + 1)]);\r\n }\r\n\r\n moveCommand(from: number, to: number): void {\r\n const cmds = [...this.commands$.getValue()];\r\n if (from < 0 || to < 0 || from >= cmds.length || to >= cmds.length || from === to) return;\r\n const [item] = cmds.splice(from, 1);\r\n cmds.splice(to, 0, item);\r\n this.commands$.next(cmds);\r\n }\r\n\r\n removeInterceptor(index: number): void {\r\n const ints = this.interceptors$.getValue();\r\n if (index < 0 || index >= ints.length) return;\r\n this.interceptors$.next([...ints.slice(0, index), ...ints.slice(index + 1)]);\r\n }\r\n\r\n registerInterceptor(method: string, url: string, alias: string): void {\r\n if (this.isPaused$.getValue()) return;\r\n const command = `cy.intercept('${method}', '${this.urlToWildcard(url, method)}').as('${alias}')`;\r\n const current = this.interceptors$.getValue();\r\n if (!current.includes(command)) {\r\n this.interceptors$.next([...current, command]);\r\n }\r\n }\r\n\r\n clearCommands(): void {\r\n this.commands$.next([]);\r\n this.interceptors$.next([]);\r\n }\r\n\r\n clearInterceptors(): void {\r\n this.interceptors$.next([]);\r\n }\r\n\r\n getCommandsSnapshot(): string[] { return this.commands$.getValue(); }\r\n getInterceptorsSnapshot(): string[] { return this.interceptors$.getValue(); }\r\n getPausedSnapshot(): boolean { return this.isPaused$.getValue(); }\r\n\r\n onCommandsChange(fn: (cmds: string[]) => void): () => void {\r\n return this.commands$.subscribe(fn);\r\n }\r\n\r\n onInterceptorsChange(fn: (ints: string[]) => void): () => void {\r\n return this.interceptors$.subscribe(fn);\r\n }\r\n\r\n onRecordingChange(fn: (isRecording: boolean) => void): () => void {\r\n return this.isRecording$.subscribe(fn);\r\n }\r\n\r\n onPauseChange(fn: (isPaused: boolean) => void): () => void {\r\n return this.isPaused$.subscribe(fn);\r\n }\r\n\r\n onSelectorNotFound(fn: (target: HTMLElement, action: 'click') => void): () => void {\r\n return this.selectorNotFound$.subscribe((v) => {\r\n if (v) fn(v.target, v.action);\r\n });\r\n }\r\n\r\n destroy(): void {\r\n this.abort.abort();\r\n history.pushState = this.origPushState;\r\n history.replaceState = this.origReplaceState;\r\n this.inputDebounceTimers.forEach((t) => clearTimeout(t));\r\n this.inputDebounceTimers.clear();\r\n }\r\n\r\n // ── DOM listeners ─────────────────────────────────────────────────────────\r\n\r\n private listenToClicks(): void {\r\n document.addEventListener(\r\n 'click',\r\n (e: Event) => {\r\n if (!this.isRecording$.getValue()) return;\r\n const target = e.target as HTMLElement;\r\n if (!target || this.isOwnElement(target)) return;\r\n const tag = target.tagName?.toLowerCase();\r\n if (tag === 'body' || tag === 'html') return;\r\n this.handleClickEvent(target);\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n private listenToInput(): void {\r\n document.addEventListener(\r\n 'input',\r\n (e: Event) => {\r\n if (!this.isRecording$.getValue()) return;\r\n const target = e.target as HTMLInputElement | HTMLTextAreaElement;\r\n if (!target || this.isOwnElement(target)) return;\r\n this.handleInputEvent(target);\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n private listenToSelect(): void {\r\n document.addEventListener(\r\n 'change',\r\n (e: Event) => {\r\n if (!this.isRecording$.getValue()) return;\r\n const target = e.target as HTMLSelectElement;\r\n if (!target || this.isOwnElement(target)) return;\r\n if (target.tagName.toLowerCase() === 'select') {\r\n this.handleSelectEvent(target);\r\n }\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n private listenToRouteChanges(): void {\r\n let lastUrl = window.location.pathname + window.location.search + window.location.hash;\r\n\r\n const addUrlCommand = (newUrl: string): void => {\r\n if (!this.isRecording$.getValue()) return;\r\n if (newUrl === lastUrl) return;\r\n this.addCommand(`cy.url().should('include', '${newUrl}')`);\r\n lastUrl = newUrl;\r\n };\r\n\r\n const wrapMethod = (type: 'pushState' | 'replaceState'): void => {\r\n const orig = history[type].bind(history);\r\n history[type] = (data: unknown, unused: string, url?: string | URL | null) => {\r\n const result = orig(data, unused, url);\r\n let newUrl = window.location.pathname + window.location.search + window.location.hash;\r\n if (typeof url === 'string' && url.length > 0) {\r\n const a = document.createElement('a');\r\n a.href = url;\r\n newUrl = a.pathname + a.search + a.hash;\r\n } else if (url instanceof URL) {\r\n newUrl = url.pathname + url.search + url.hash;\r\n }\r\n addUrlCommand(newUrl);\r\n return result;\r\n };\r\n };\r\n\r\n wrapMethod('pushState');\r\n wrapMethod('replaceState');\r\n\r\n window.addEventListener(\r\n 'popstate',\r\n () => {\r\n const newUrl = window.location.pathname + window.location.search + window.location.hash;\r\n addUrlCommand(newUrl);\r\n },\r\n { signal: this.abort.signal }\r\n );\r\n }\r\n\r\n // ── Click helpers ─────────────────────────────────────────────────────────\r\n\r\n private handleClickEvent(target: HTMLElement): void {\r\n // Bubble up from non-interactive span/div inside button or mat-option\r\n if (!this.isInteractiveElement(target)) {\r\n const tag = target.tagName.toLowerCase();\r\n if (\r\n (tag === 'span' || tag === 'div') &&\r\n target.parentElement &&\r\n (target.parentElement.tagName.toLowerCase() === 'button' ||\r\n target.parentElement.tagName.toLowerCase() === 'mat-option') &&\r\n (target.parentElement.hasAttribute('data-cy') || target.parentElement.hasAttribute('id'))\r\n ) {\r\n target = target.parentElement;\r\n }\r\n const matSelect = target.closest('mat-select');\r\n if (matSelect) {\r\n const sel = this.getReliableSelector(matSelect as HTMLElement);\r\n if (sel) {\r\n this.addCommand(`cy.get('${sel}').click()`);\r\n } else {\r\n this.selectorNotFound$.next({ target: matSelect as HTMLElement, action: 'click' });\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const tag = target.tagName.toLowerCase();\r\n if (tag === 'input' || tag === 'textarea' || tag === 'select') {\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) this.selectorNotFound$.next({ target, action: 'click' });\r\n return;\r\n }\r\n\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) {\r\n this.selectorNotFound$.next({ target, action: 'click' });\r\n return;\r\n }\r\n\r\n const selector = this.getReliableSelector(container);\r\n if (selector === OWN_SELECTOR) return;\r\n\r\n if (tag === 'mat-option') {\r\n this.handleMatOptionClick(target, selector);\r\n return;\r\n }\r\n\r\n this.addGenericCommand({\r\n selector,\r\n action: (s) => `cy.get('${s}').click()`,\r\n });\r\n }\r\n\r\n private handleMatOptionClick(target: HTMLElement, selector: string | null): void {\r\n const matSelect = target.closest('mat-select');\r\n let dataCy: string | null = null;\r\n if (matSelect) dataCy = matSelect.closest('[data-cy]')?.getAttribute('data-cy') ?? null;\r\n if (!dataCy) dataCy = target.closest('[data-cy]')?.getAttribute('data-cy') ?? null;\r\n if (dataCy) {\r\n this.addCommand(`cy.get('[data-cy=\"${dataCy}\"]').click()`);\r\n return;\r\n }\r\n if (selector) {\r\n this.addCommand(`cy.get('${selector}').eq(0).click()`);\r\n } else {\r\n this.selectorNotFound$.next({ target, action: 'click' });\r\n }\r\n }\r\n\r\n // ── Input helpers ─────────────────────────────────────────────────────────\r\n\r\n private handleInputEvent(target: HTMLInputElement | HTMLTextAreaElement): void {\r\n const tag = target.tagName.toLowerCase();\r\n const isText = tag === 'textarea' || (tag === 'input' && (INPUT_TYPES as readonly string[]).includes(target.type));\r\n if (!isText) return;\r\n\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) return;\r\n\r\n if (this.inputDebounceTimers.has(target)) {\r\n clearTimeout(this.inputDebounceTimers.get(target));\r\n }\r\n this.inputDebounceTimers.set(\r\n target,\r\n setTimeout(() => {\r\n const selector = this.getReliableSelector(container);\r\n const value = target.value.replace(/'/g, \"\\\\'\");\r\n this.addGenericCommand({\r\n selector,\r\n action: (s) => `cy.get('${s}').clear().type('${value}')`,\r\n });\r\n this.inputDebounceTimers.delete(target);\r\n }, 1000)\r\n );\r\n }\r\n\r\n // ── Select helpers ────────────────────────────────────────────────────────\r\n\r\n private handleSelectEvent(target: HTMLSelectElement): void {\r\n const container = target.closest<HTMLElement>('[data-cy], [data-testid], [aria-label], [id]');\r\n if (!container) return;\r\n const selector = this.getReliableSelector(container);\r\n const value = target.value.replace(/'/g, \"\\\\'\");\r\n this.addGenericCommand({\r\n selector,\r\n action: (s) => `cy.get('${s}').select('${value}')`,\r\n });\r\n }\r\n\r\n // ── Shared helpers ────────────────────────────────────────────────────────\r\n\r\n private addGenericCommand(opts: {\r\n selector: string | null;\r\n action: (s: string) => string;\r\n }): void {\r\n if (!opts.selector || this.isOwnSelector(opts.selector)) return;\r\n this.addCommand(opts.action(opts.selector));\r\n }\r\n\r\n private getReliableSelector(el: HTMLElement): string | null {\r\n const strategy = this.selectorStrategy;\r\n const dataCy = el.getAttribute('data-cy');\r\n const dataTestid = el.getAttribute('data-testid');\r\n const ariaLabel = el.getAttribute('aria-label');\r\n const dataDotCy = el.getAttribute('data.cy');\r\n\r\n const rawId = el.id;\r\n const validId = rawId &&\r\n rawId.length < 25 &&\r\n /^[a-zA-Z][\\w-]*$/.test(rawId) &&\r\n !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) &&\r\n !/^\\d+$/.test(rawId) ? rawId : null;\r\n\r\n switch (strategy) {\r\n case 'data-testid':\r\n if (dataTestid) return `[data-testid=\"${dataTestid}\"]`;\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n return validId ? `#${validId}` : null;\r\n case 'aria-label':\r\n if (ariaLabel) return `[aria-label=\"${ariaLabel}\"]`;\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n return validId ? `#${validId}` : null;\r\n case 'id':\r\n if (validId) return `#${validId}`;\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n return dataTestid ? `[data-testid=\"${dataTestid}\"]` : null;\r\n default: // 'data-cy'\r\n if (dataCy) return `[data-cy=\"${dataCy}\"]`;\r\n if (dataDotCy) return `[data.cy=\"${dataDotCy}\"]`;\r\n return validId ? `#${validId}` : null;\r\n }\r\n }\r\n\r\n private isInteractiveElement(target: EventTarget | null): boolean {\r\n if (!(target instanceof HTMLElement)) return false;\r\n const tag = target.tagName.toLowerCase();\r\n return ['select', 'option', 'input', 'textarea', 'button'].includes(tag);\r\n }\r\n\r\n private isOwnSelector(selector: string | null): boolean {\r\n return selector === OWN_SELECTOR;\r\n }\r\n\r\n private isOwnElement(target: HTMLElement): boolean {\r\n return !!target.closest('[data-cy=\"lib-e2e-cypress-for-dummys\"]');\r\n }\r\n\r\n private urlToWildcard(url: string, method: string): string {\r\n const u = new URL(url, 'http://localhost');\r\n if (method.toUpperCase() === 'GET' && u.search) {\r\n return `**${u.pathname}/**`;\r\n }\r\n return `**${u.pathname}`;\r\n }\r\n}\r\n","import { openDB, type IDBPDatabase } from 'idb';\r\nimport { DB_SCHEMA } from '../models/db-schema.model';\r\nimport { normalizeBlock } from '../utils/code-format.utils';\r\n\r\ninterface TestRecord { id: number; name: string; createdAt: number; tags?: string[]; notes?: string; }\r\ninterface CommandRecord { id: number; command: string; testId: number; createdAt: number; }\r\ninterface InterceptorRecord { id: number; interceptor: string; testId: number; createdAt: number; }\r\ninterface ConfigRecord { id: number; [key: string]: unknown; }\r\n\r\nexport interface TestWithDetails extends TestRecord {\r\n commands: string[];\r\n interceptors: string[];\r\n}\r\n\r\nexport interface TestDetail extends TestWithDetails {\r\n cypressCommands: string[];\r\n itBlock: string;\r\n interceptorsBlock: string;\r\n}\r\n\r\nexport class PersistenceService {\r\n private _db: Promise<IDBPDatabase> | null = null;\r\n\r\n // dbName is overridable so tests can use unique names for isolation.\r\n constructor(private readonly dbName: string = DB_SCHEMA.name) {}\r\n\r\n private getDB(): Promise<IDBPDatabase> {\r\n if (!this._db) {\r\n this._db = openDB(this.dbName, DB_SCHEMA.version, {\r\n upgrade(database) {\r\n for (const store of DB_SCHEMA.stores) {\r\n if (!database.objectStoreNames.contains(store.name)) {\r\n const os = database.createObjectStore(store.name, {\r\n keyPath: store.keyPath,\r\n autoIncrement: store.autoIncrement,\r\n });\r\n for (const index of store.indexes) {\r\n os.createIndex(index.name, index.keyPath, { unique: index.unique });\r\n }\r\n }\r\n }\r\n },\r\n });\r\n }\r\n return this._db;\r\n }\r\n\r\n // ── Tests ─────────────────────────────────────────────────────────────────\r\n\r\n async insertTest(name: string, commands: string[] = [], interceptors: string[] = [], tags: string[] = [], notes?: string): Promise<number> {\r\n const db = await this.getDB();\r\n const record: Omit<TestRecord, 'id'> = { name, createdAt: Date.now(), ...(tags.length ? { tags } : {}), ...(notes ? { notes } : {}) };\r\n const id = await db.add('tests', record) as number;\r\n if (commands.length) await this.insertCommands(commands, id);\r\n if (interceptors.length) await this.insertInterceptors(interceptors, id);\r\n return id;\r\n }\r\n\r\n async getAllTests(): Promise<TestWithDetails[]> {\r\n const db = await this.getDB();\r\n const tests = await db.getAll('tests') as TestRecord[];\r\n return Promise.all(\r\n tests.map(async (test) => ({\r\n ...test,\r\n commands: await this.getCommandStrings(test.id),\r\n interceptors: await this.getInterceptorStrings(test.id),\r\n }))\r\n );\r\n }\r\n\r\n async getTestById(testId: number): Promise<TestDetail | null> {\r\n const db = await this.getDB();\r\n const record = await db.get('tests', testId) as TestRecord | undefined;\r\n if (!record) return null;\r\n\r\n const commands = await this.getCommandStrings(testId);\r\n const interceptors = await this.getInterceptorStrings(testId);\r\n const itBlock = `it('${record.name}', () => {\\n${commands.map(c => normalizeBlock(c, ' ')).join('\\n')}\\n});`;\r\n const interceptorsBlock = interceptors.length\r\n ? ' // Auto-generated Cypress interceptors\\n' +\r\n interceptors.map(i => normalizeBlock(i, ' ')).join('\\n') + '\\n'\r\n : '';\r\n\r\n return { ...record, commands, interceptors, cypressCommands: commands, itBlock, interceptorsBlock };\r\n }\r\n\r\n async deleteTest(id: number): Promise<void> {\r\n const db = await this.getDB();\r\n await db.delete('tests', id);\r\n await this.deleteCommandsByTestId(id);\r\n await this.deleteInterceptorsByTestId(id);\r\n }\r\n\r\n // ── Commands ──────────────────────────────────────────────────────────────\r\n\r\n async insertCommands(commands: string[], testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n await Promise.all(\r\n commands.map((command) => db.add('commands', { command, testId, createdAt: Date.now() }))\r\n );\r\n }\r\n\r\n async getCommandsByTestId(testId: number): Promise<CommandRecord[]> {\r\n const db = await this.getDB();\r\n return db.getAllFromIndex('commands', 'testId', testId) as Promise<CommandRecord[]>;\r\n }\r\n\r\n private async getCommandStrings(testId: number): Promise<string[]> {\r\n return (await this.getCommandsByTestId(testId)).map((r) => r.command).filter(Boolean);\r\n }\r\n\r\n private async deleteCommandsByTestId(testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n const rows = await this.getCommandsByTestId(testId);\r\n const tx = db.transaction('commands', 'readwrite');\r\n await Promise.all(rows.map((r) => tx.store.delete(r.id)));\r\n await tx.done;\r\n }\r\n\r\n // ── Interceptors ──────────────────────────────────────────────────────────\r\n\r\n async insertInterceptors(interceptors: string[], testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n await Promise.all(\r\n interceptors.map((interceptor) => db.add('interceptors', { interceptor, testId, createdAt: Date.now() }))\r\n );\r\n }\r\n\r\n async getInterceptorsByTestId(testId: number): Promise<InterceptorRecord[]> {\r\n const db = await this.getDB();\r\n return db.getAllFromIndex('interceptors', 'testId', testId) as Promise<InterceptorRecord[]>;\r\n }\r\n\r\n private async getInterceptorStrings(testId: number): Promise<string[]> {\r\n return (await this.getInterceptorsByTestId(testId)).map((r) => r.interceptor).filter(Boolean);\r\n }\r\n\r\n async deleteInterceptorsByTestId(testId: number): Promise<void> {\r\n const db = await this.getDB();\r\n const rows = await this.getInterceptorsByTestId(testId);\r\n const tx = db.transaction('interceptors', 'readwrite');\r\n await Promise.all(rows.map((r) => tx.store.delete(r.id)));\r\n await tx.done;\r\n }\r\n\r\n // ── Configuration ─────────────────────────────────────────────────────────\r\n\r\n async setConfig(config: Record<string, unknown>): Promise<void> {\r\n const db = await this.getDB();\r\n const records = await db.getAll('configuration') as ConfigRecord[];\r\n const current = records[0] ?? {};\r\n const merged = { ...current, ...config };\r\n if ((current as ConfigRecord).id) {\r\n await db.put('configuration', merged);\r\n } else {\r\n await db.add('configuration', merged);\r\n }\r\n }\r\n\r\n async setConfigKey(key: string, value: unknown): Promise<void> {\r\n return this.setConfig({ [key]: value });\r\n }\r\n\r\n async getConfig(key: string): Promise<Record<string, unknown> | null> {\r\n const db = await this.getDB();\r\n const records = await db.getAll('configuration') as ConfigRecord[];\r\n if (!records.length) return null;\r\n const config = records[0];\r\n return Object.prototype.hasOwnProperty.call(config, key) ? { [key]: config[key] } : null;\r\n }\r\n\r\n async getGeneralConfig(): Promise<ConfigRecord | null> {\r\n const db = await this.getDB();\r\n const records = await db.getAll('configuration') as ConfigRecord[];\r\n return records[0] ?? null;\r\n }\r\n\r\n // ── Bulk operations ───────────────────────────────────────────────────────\r\n\r\n async clearAllData(): Promise<void> {\r\n const db = await this.getDB();\r\n await Promise.all([\r\n db.clear('tests'),\r\n db.clear('commands'),\r\n db.clear('interceptors'),\r\n ]);\r\n }\r\n\r\n async ingestFileData(tests: Record<string, unknown>[], interceptors: Record<string, unknown>[]): Promise<void> {\r\n await Promise.all([\r\n this.bulkInsertWithoutId('tests', tests),\r\n this.bulkInsertWithoutId('interceptors', interceptors),\r\n ]);\r\n }\r\n\r\n async requestDirectoryPermissions(): Promise<void> {\r\n if (!('showDirectoryPicker' in window)) {\r\n throw new Error('File System Access API not supported');\r\n }\r\n const dirHandle = await window.showDirectoryPicker();\r\n await this.setConfigKey('cypressDirectoryHandle', dirHandle);\r\n await this.setConfigKey('allowReadWriteFiles', 'true');\r\n }\r\n\r\n private async bulkInsertWithoutId(store: string, items: Record<string, unknown>[]): Promise<void> {\r\n if (!Array.isArray(items)) return;\r\n const db = await this.getDB();\r\n for (const item of items) {\r\n const { id: _id, ...rest } = item;\r\n await db.add(store, rest);\r\n }\r\n }\r\n}\r\n\r\nexport const persistenceService = new PersistenceService();\r\n","import { type RecordingService } from './recording.service';\r\n\r\nconst INTERCEPTED_METHODS = ['GET', 'POST', 'PUT'] as const;\r\ntype InterceptedMethod = (typeof INTERCEPTED_METHODS)[number];\r\n\r\nexport function generateAlias(method: string, url: string): string {\r\n try {\r\n const u = new URL(url, 'http://localhost');\r\n const path = u.pathname\r\n .replace(/[^a-zA-Z0-9]/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/(^-)|(-$)/g, '');\r\n return `${method.toLowerCase()}-${path}`;\r\n } catch {\r\n return `${method.toLowerCase()}-intercepted-request`;\r\n }\r\n}\r\n\r\nfunction buildValidations(base: string, obj: Record<string, unknown>): string {\r\n return Object.keys(obj)\r\n .filter((key) => key !== 'id' && key !== 'uid')\r\n .map((key) => `expect(${base}.${key}).to.equal(${JSON.stringify(obj[key])});`)\r\n .join('\\n');\r\n}\r\n\r\nfunction buildCyWaitCommand(\r\n method: string,\r\n alias: string,\r\n extendedHttp: boolean,\r\n requestBody: Record<string, unknown> | null,\r\n responseBody: Record<string, unknown> | null\r\n): string {\r\n if (extendedHttp && method === 'GET' && responseBody) {\r\n const validations = buildValidations('interception.response.body', responseBody);\r\n return `cy.wait('@${alias}').then((interception) => {\\n if (interception.response) {\\n${validations}\\n }\\n})`;\r\n }\r\n if (extendedHttp && (method === 'POST' || method === 'PUT') && requestBody) {\r\n const validations = buildValidations('interception.request.body', requestBody);\r\n return `cy.wait('@${alias}').then((interception) => {\\n${validations}\\n})`;\r\n }\r\n return `cy.wait('@${alias}').then((interception) => { })`;\r\n}\r\n\r\nfunction parseJsonObject(text: string): Record<string, unknown> | null {\r\n try {\r\n const parsed = JSON.parse(text);\r\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\r\n return parsed as Record<string, unknown>;\r\n }\r\n } catch {\r\n // Non-JSON or array — fall through\r\n }\r\n return null;\r\n}\r\n\r\nfunction parseRequestBody(init?: RequestInit): Record<string, unknown> | null {\r\n const body = init?.body;\r\n if (typeof body === 'string') return parseJsonObject(body);\r\n return null;\r\n}\r\n\r\nfunction resolveUrl(input: RequestInfo | URL): string {\r\n if (typeof input === 'string') return input;\r\n if (input instanceof URL) return input.href;\r\n return input.url;\r\n}\r\n\r\nfunction resolveMethod(input: RequestInfo | URL, init?: RequestInit): string {\r\n if (init?.method) return init.method.toUpperCase();\r\n if (input instanceof Request) return input.method.toUpperCase();\r\n return 'GET';\r\n}\r\n\r\nexport class HttpMonitor {\r\n private originalFetch: typeof window.fetch | null = null;\r\n private originalXHR: typeof XMLHttpRequest | null = null;\r\n\r\n constructor(private readonly recording: RecordingService) {}\r\n\r\n install(): void {\r\n this.installFetch();\r\n this.installXhr();\r\n }\r\n\r\n uninstall(): void {\r\n this.uninstallFetch();\r\n this.uninstallXhr();\r\n }\r\n\r\n isExtendedHttpEnabled(): boolean {\r\n return localStorage.getItem('extendedHttpCommands') === 'true';\r\n }\r\n\r\n private installFetch(): void {\r\n if (this.originalFetch) return;\r\n const originalFetch = window.fetch;\r\n this.originalFetch = originalFetch;\r\n\r\n window.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\r\n const response = await originalFetch(input, init);\r\n try {\r\n await this.handleFetchInterception(input, init, response.clone());\r\n } catch {\r\n // Never let monitoring errors break the actual request\r\n }\r\n return response;\r\n };\r\n }\r\n\r\n private uninstallFetch(): void {\r\n if (!this.originalFetch) return;\r\n window.fetch = this.originalFetch;\r\n this.originalFetch = null;\r\n }\r\n\r\n private installXhr(): void {\r\n if (this.originalXHR) return;\r\n this.originalXHR = window.XMLHttpRequest;\r\n const OrigXHR = this.originalXHR;\r\n const handleXhrInterception = this.handleXhrInterception.bind(this);\r\n\r\n window.XMLHttpRequest = class extends OrigXHR {\r\n private _xhrMethod = 'GET';\r\n private _xhrUrl = '';\r\n private _xhrRequestBody: Record<string, unknown> | null = null;\r\n\r\n override open(\r\n method: string,\r\n url: string | URL,\r\n async = true,\r\n user?: string | null,\r\n password?: string | null\r\n ): void {\r\n this._xhrMethod = method.toUpperCase();\r\n this._xhrUrl = url instanceof URL ? url.href : url;\r\n super.open(method, url as string, async, user, password);\r\n }\r\n\r\n override send(body?: Document | XMLHttpRequestBodyInit | null): void {\r\n if (typeof body === 'string') {\r\n this._xhrRequestBody = parseJsonObject(body);\r\n }\r\n this.addEventListener('load', () => {\r\n try {\r\n handleXhrInterception(\r\n this._xhrMethod,\r\n this._xhrUrl,\r\n this._xhrRequestBody,\r\n this.responseText\r\n );\r\n } catch {\r\n // Never let monitoring errors surface\r\n }\r\n });\r\n super.send(body);\r\n }\r\n } as unknown as typeof XMLHttpRequest;\r\n }\r\n\r\n private uninstallXhr(): void {\r\n if (!this.originalXHR) return;\r\n window.XMLHttpRequest = this.originalXHR;\r\n this.originalXHR = null;\r\n }\r\n\r\n private async handleFetchInterception(\r\n input: RequestInfo | URL,\r\n init: RequestInit | undefined,\r\n responseClone: Response\r\n ): Promise<void> {\r\n const method = resolveMethod(input, init);\r\n if (!(INTERCEPTED_METHODS as readonly string[]).includes(method)) return;\r\n\r\n const url = resolveUrl(input);\r\n const alias = generateAlias(method, url);\r\n\r\n this.recording.registerInterceptor(method, url, alias);\r\n\r\n const extendedHttp = this.isExtendedHttpEnabled();\r\n const requestBody = extendedHttp ? parseRequestBody(init) : null;\r\n let responseBody: Record<string, unknown> | null = null;\r\n if (extendedHttp) {\r\n try {\r\n responseBody = parseJsonObject(await responseClone.text());\r\n } catch {\r\n // Unreadable body — continue without validations\r\n }\r\n }\r\n\r\n const cmd = buildCyWaitCommand(method, alias, extendedHttp, requestBody, responseBody);\r\n this.recording.addCommand(cmd);\r\n }\r\n\r\n private handleXhrInterception(\r\n method: string,\r\n url: string,\r\n requestBody: Record<string, unknown> | null,\r\n responseText: string\r\n ): void {\r\n if (!(INTERCEPTED_METHODS as readonly string[]).includes(method as InterceptedMethod)) return;\r\n\r\n const alias = generateAlias(method, url);\r\n this.recording.registerInterceptor(method, url, alias);\r\n\r\n const extendedHttp = this.isExtendedHttpEnabled();\r\n const responseBody = extendedHttp ? parseJsonObject(responseText) : null;\r\n\r\n const cmd = buildCyWaitCommand(method, alias, extendedHttp, requestBody, responseBody);\r\n this.recording.addCommand(cmd);\r\n }\r\n}\r\n\r\n","export const SCROLLBAR_STYLES = `\r\n.swal2-popup::-webkit-scrollbar,\r\n.swal2-html-container::-webkit-scrollbar,\r\n.swal2-content::-webkit-scrollbar,\r\n.swal2-container::-webkit-scrollbar {\r\n width: 5px;\r\n height: 5px;\r\n background: transparent;\r\n}\r\n.swal2-popup::-webkit-scrollbar-thumb,\r\n.swal2-html-container::-webkit-scrollbar-thumb,\r\n.swal2-content::-webkit-scrollbar-thumb,\r\n.swal2-container::-webkit-scrollbar-thumb {\r\n background: #30363d;\r\n border-radius: 3px;\r\n}\r\n.swal2-popup::-webkit-scrollbar-thumb:hover,\r\n.swal2-html-container::-webkit-scrollbar-thumb:hover,\r\n.swal2-content::-webkit-scrollbar-thumb:hover {\r\n background: #484f58;\r\n}\r\n.swal2-popup::-webkit-scrollbar-track,\r\n.swal2-html-container::-webkit-scrollbar-track,\r\n.swal2-content::-webkit-scrollbar-track,\r\n.swal2-container::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n.swal2-popup, .swal2-html-container, .swal2-content, .swal2-container {\r\n scrollbar-width: thin;\r\n scrollbar-color: #30363d transparent;\r\n}\r\n`;\r\n\r\nexport const LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES = `\r\n.swal2-container, .swal2-popup {\r\n z-index: 99999 !important;\r\n}\r\n.swal2-container {\r\n padding: 0 !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n}\r\n.swal2-popup {\r\n background: #161b22 !important;\r\n color: #e6edf3 !important;\r\n border-radius: 12px !important;\r\n box-shadow: 0 24px 64px rgba(0,0,0,0.72), 0 0 0 1px #30363d !important;\r\n border: none !important;\r\n padding: 0 !important;\r\n min-width: 400px;\r\n max-width: 90vw;\r\n min-height: 200px;\r\n max-height: 90vh;\r\n}\r\n/* Override SweetAlert2 v11's display:grid on .swal2-popup.swal2-modal */\r\n.swal2-popup.swal2-modal {\r\n display: flex !important;\r\n flex-direction: column !important;\r\n align-items: stretch !important;\r\n overflow: hidden !important;\r\n}\r\n.swal2-header {\r\n flex-shrink: 0 !important;\r\n flex-grow: 0 !important;\r\n overflow: hidden !important;\r\n}\r\n.swal2-title {\r\n color: #e6edf3 !important;\r\n font-weight: 600 !important;\r\n font-size: 14px !important;\r\n background: #161b22;\r\n padding: 14px 48px 13px 18px !important;\r\n margin: 0 !important;\r\n border-bottom: 1px solid #21262d;\r\n text-align: left !important;\r\n letter-spacing: 0.1px;\r\n white-space: nowrap !important;\r\n overflow: hidden !important;\r\n text-overflow: ellipsis !important;\r\n}\r\n.swal2-close {\r\n position: absolute !important;\r\n top: 10px !important;\r\n right: 12px !important;\r\n color: #8b949e !important;\r\n font-size: 1.1rem !important;\r\n z-index: 1 !important;\r\n border-radius: 6px !important;\r\n width: 28px !important;\r\n height: 28px !important;\r\n line-height: 28px !important;\r\n transition: background 0.15s, color 0.15s !important;\r\n}\r\n.swal2-close:hover {\r\n background: #21262d !important;\r\n color: #e6edf3 !important;\r\n}\r\n/* In SweetAlert2 v11, .swal2-html-container is a direct child of .swal2-popup */\r\n.swal2-html-container {\r\n flex: 1 !important;\r\n min-height: 0 !important;\r\n background: #161b22;\r\n padding: 0 !important;\r\n margin: 0 !important;\r\n width: 100%;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n align-items: stretch;\r\n box-sizing: border-box;\r\n overflow: hidden !important;\r\n}\r\n/* The single wrapper div we inject inside each modal fills the container */\r\n.swal2-html-container > div {\r\n flex: 1 !important;\r\n min-height: 0 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n overflow: hidden !important;\r\n}\r\n.swal2-actions, .swal2-footer {\r\n flex-shrink: 0 !important;\r\n flex-grow: 0 !important;\r\n}\r\n`;\r\n\r\nexport function injectStyles(css: string, id: string): void {\r\n if (document.getElementById(id)) return;\r\n const style = document.createElement('style');\r\n style.id = id;\r\n style.innerHTML = css;\r\n document.head.appendChild(style);\r\n}\r\n","export function makeModalResizable(\r\n modal: HTMLElement,\r\n options?: { minWidth?: number; minHeight?: number }\r\n): () => void {\r\n if (!modal || modal.querySelector('.modal-resizer')) return () => { /* no-op */ };\r\n\r\n const rect = modal.getBoundingClientRect();\r\n modal.style.position = 'fixed';\r\n modal.style.top = `${rect.top}px`;\r\n modal.style.left = `${rect.left}px`;\r\n modal.style.width = `${rect.width}px`;\r\n modal.style.margin = '0';\r\n modal.style.resize = 'both';\r\n modal.style.overflow = 'hidden';\r\n modal.style.minWidth = (options?.minWidth ?? 320) + 'px';\r\n modal.style.minHeight = (options?.minHeight ?? 180) + 'px';\r\n\r\n const resizer = document.createElement('div');\r\n resizer.className = 'modal-resizer';\r\n resizer.style.position = 'absolute';\r\n resizer.style.width = '16px';\r\n resizer.style.height = '16px';\r\n resizer.style.right = '2px';\r\n resizer.style.bottom = '2px';\r\n resizer.style.cursor = 'nwse-resize';\r\n resizer.style.background = 'rgba(0,0,0,0.1)';\r\n resizer.style.zIndex = '10';\r\n modal.appendChild(resizer);\r\n\r\n let isResizing = false;\r\n let lastX = 0;\r\n let lastY = 0;\r\n\r\n const mouseMove = (e: MouseEvent): void => {\r\n if (!isResizing) return;\r\n const dx = e.clientX - lastX;\r\n const dy = e.clientY - lastY;\r\n lastX = e.clientX;\r\n lastY = e.clientY;\r\n const rect = modal.getBoundingClientRect();\r\n modal.style.width = rect.width + dx + 'px';\r\n modal.style.height = rect.height + dy + 'px';\r\n };\r\n\r\n const mouseUp = (): void => {\r\n isResizing = false;\r\n document.body.style.userSelect = '';\r\n };\r\n\r\n resizer.addEventListener('mousedown', (e) => {\r\n e.preventDefault();\r\n isResizing = true;\r\n lastX = e.clientX;\r\n lastY = e.clientY;\r\n document.body.style.userSelect = 'none';\r\n });\r\n\r\n window.addEventListener('mousemove', mouseMove);\r\n window.addEventListener('mouseup', mouseUp);\r\n\r\n return () => {\r\n window.removeEventListener('mousemove', mouseMove);\r\n window.removeEventListener('mouseup', mouseUp);\r\n if (resizer.parentNode) resizer.parentNode.removeChild(resizer);\r\n };\r\n}\r\n\r\nfunction applyDraggable(swal: HTMLElement, dragArea: HTMLElement): void {\r\n let isDragging = false;\r\n let offsetX = 0;\r\n let offsetY = 0;\r\n\r\n dragArea.style.cursor = 'move';\r\n dragArea.onmousedown = (e: MouseEvent) => {\r\n isDragging = true;\r\n const rect = swal.getBoundingClientRect();\r\n offsetX = e.clientX - rect.left;\r\n offsetY = e.clientY - rect.top;\r\n document.onmousemove = (ev: MouseEvent) => {\r\n if (isDragging) {\r\n swal.style.position = 'fixed';\r\n swal.style.margin = '0';\r\n swal.style.left = `${ev.clientX - offsetX}px`;\r\n swal.style.top = `${ev.clientY - offsetY}px`;\r\n }\r\n };\r\n document.onmouseup = () => {\r\n isDragging = false;\r\n document.onmousemove = null;\r\n document.onmouseup = null;\r\n };\r\n };\r\n}\r\n\r\nfunction resolveDragArea(swal: HTMLElement): HTMLElement | null {\r\n return (swal.querySelector('.swal2-header') as HTMLElement | null)\r\n ?? (swal.querySelector('.swal2-title') as HTMLElement | null);\r\n}\r\n\r\nexport function makeSwalDraggable(): void {\r\n const popups = document.querySelectorAll('.swal2-popup');\r\n if (!popups.length) return;\r\n const swal = popups[popups.length - 1] as HTMLElement;\r\n const dragArea = resolveDragArea(swal);\r\n if (!dragArea) return;\r\n applyDraggable(swal, dragArea);\r\n}\r\n\r\nexport function makeSwalDraggableByContentId(contentId: string): void {\r\n const content = document.getElementById(contentId);\r\n if (!content) {\r\n makeSwalDraggable();\r\n return;\r\n }\r\n const swal = (content.closest('.swal2-popup') as HTMLElement | null)\r\n ?? (document.querySelector('.swal2-popup') as HTMLElement | null);\r\n if (!swal) return;\r\n const dragArea = resolveDragArea(swal);\r\n if (!dragArea) return;\r\n applyDraggable(swal, dragArea);\r\n}\r\n\r\nexport function setSwal2DataCyAttribute(dataCy = 'lib-e2e-cypress-for-dummys'): void {\r\n document.querySelector('.swal2-container')?.setAttribute('data-cy', dataCy);\r\n document.querySelector('.swal2-html-container')?.setAttribute('data-cy', dataCy);\r\n document.querySelector('.swal2-title')?.setAttribute('data-cy', dataCy);\r\n}\r\n","export function showToast(message: string, isSuccess = true): void {\r\n const toast = document.createElement('div');\r\n toast.textContent = message;\r\n toast.style.position = 'fixed';\r\n toast.style.top = '30px';\r\n toast.style.right = '30px';\r\n toast.style.padding = '16px 24px';\r\n toast.style.background = isSuccess ? '#4caf50' : '#f44336';\r\n toast.style.color = '#fff';\r\n toast.style.borderRadius = '8px';\r\n toast.style.boxShadow = '0 2px 8px rgba(0,0,0,0.2)';\r\n toast.style.zIndex = '9999';\r\n toast.style.fontSize = '1rem';\r\n toast.style.fontWeight = 'bold';\r\n toast.style.pointerEvents = 'none';\r\n document.body.appendChild(toast);\r\n setTimeout(() => toast.remove(), 3000);\r\n}\r\n","export const TEST_PREVISUALIZER_STYLES = `\n :host { display: flex; flex-direction: column; flex: 1; min-height: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; overflow: hidden; }\n * { box-sizing: border-box; }\n .toolbar {\n display: flex; gap: 6px; padding: 10px 12px; flex-shrink: 0;\n background: #161b22; border-bottom: 1px solid #21262d;\n }\n button {\n padding: 5px 12px; border: none; border-radius: 6px; cursor: pointer;\n font-size: 11px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s; letter-spacing: 0.1px;\n }\n button:hover { background: #30363d; color: #e6edf3; }\n button.active { background: #2f81f7; color: #fff; }\n .section { padding: 10px 12px; flex-shrink: 0; }\n .section.section-cmds { flex: 1; min-height: 0; display: flex; flex-direction: column; }\n .section-title {\n font-size: 10px; font-weight: 600; color: #484f58; text-transform: uppercase;\n letter-spacing: 0.8px; margin-bottom: 7px; flex-shrink: 0;\n }\n .list {\n overflow-y: auto; background: #0d1117;\n border-radius: 8px; padding: 6px 8px;\n border: 1px solid #21262d;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .section-cmds .list { flex: 1; min-height: 0; }\n .list::-webkit-scrollbar { width: 4px; }\n .list::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .item {\n display: flex; align-items: flex-start; gap: 6px;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 11px;\n color: #c9d1d9; padding: 4px 8px; border-radius: 4px;\n word-break: break-all; line-height: 1.65;\n border-left: 2px solid transparent;\n transition: background 0.1s, border-color 0.1s;\n }\n .item:hover { background: #161b22; border-left-color: #2f81f7; }\n .cmd-text { flex: 1; }\n .item-actions {\n display: flex; gap: 3px; flex-shrink: 0;\n opacity: 0; transition: opacity 0.15s;\n }\n .item:hover .item-actions { opacity: 1; }\n .btn-step {\n width: 20px; height: 20px; border: none; border-radius: 3px; cursor: pointer;\n font-size: 12px; background: transparent; color: #484f58;\n transition: background 0.12s, color 0.12s;\n display: flex; align-items: center; justify-content: center;\n padding: 0; line-height: 1;\n }\n .btn-step:hover { background: #30363d; color: #e6edf3; }\n .btn-step-del:hover { background: rgba(248,81,73,0.15); color: #f85149; }\n .empty { color: #484f58; font-size: 12px; padding: 20px 8px; text-align: center; }\n`;\n","import { escHtml } from '../../utils/html.utils';\n\nexport function renderTestPrevisualizer(\n commands: string[],\n interceptors: string[],\n showInterceptors: boolean,\n editable: boolean,\n t: (key: string) => string,\n): string {\n const editControls = (idx: number, total: number) => editable ? `\n <span class=\"item-actions\">\n <button class=\"btn-step\" data-move-up=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.UP_TITLE')}\" ${idx === 0 ? 'disabled style=\"opacity:.3\"' : ''}>↑</button>\n <button class=\"btn-step\" data-move-dn=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.DOWN_TITLE')}\" ${idx === total - 1 ? 'disabled style=\"opacity:.3\"' : ''}>↓</button>\n <button class=\"btn-step btn-step-del\" data-del=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.DEL_TITLE')}\">✕</button>\n </span>` : '';\n\n const cmdItems = commands.length\n ? commands.map((c, i) => `\n <div class=\"item\">\n <span class=\"cmd-text\">${escHtml(c)}</span>\n ${editControls(i, commands.length)}\n </div>`).join('')\n : `<div class=\"empty\">${t('TEST_PREVISUALIZER.NO_CMDS_YET')}</div>`;\n\n const icpEditControls = (idx: number) => editable\n ? `<span class=\"item-actions\"><button class=\"btn-step btn-step-del\" data-del-icp=\"${idx}\" title=\"${t('TEST_PREVISUALIZER.DEL_TITLE')}\">✕</button></span>`\n : '';\n\n const icpSection = showInterceptors\n ? `<div class=\"section\" data-section=\"interceptors\">\n <div class=\"section-title\">${t('TEST_PREVISUALIZER.INTERCEPTORS')}</div>\n <div class=\"list\">\n ${\n interceptors.length\n ? interceptors.map((ic, idx) => `\n <div class=\"item\">\n <span class=\"cmd-text\">${escHtml(ic)}</span>\n ${icpEditControls(idx)}\n </div>`).join('')\n : `<div class=\"empty\">${t('TEST_PREVISUALIZER.NO_ICP_SHORT')}</div>`\n }\n </div>\n <button style=\"margin-top:6px\" data-action=\"copy-icp\">${t('TEST_PREVISUALIZER.COPY_ICP_BTN')}</button>\n </div>`\n : '';\n\n return `\n <div class=\"toolbar\">\n <button data-action=\"copy\">${t('TEST_PREVISUALIZER.COPY_CMDS_BTN')}</button>\n <button data-action=\"toggle-icp\" class=\"${showInterceptors ? 'active' : ''}\">\n ${showInterceptors ? t('TEST_PREVISUALIZER.HIDE_INTERCEPTORS') : t('TEST_PREVISUALIZER.SHOW_INTERCEPTORS')} (${interceptors.length})\n </button>\n </div>\n <div class=\"section section-cmds\">\n <div class=\"section-title\">${t('TEST_PREVISUALIZER.SECTION_COMMANDS')} (${commands.length})</div>\n <div class=\"list\" data-ref=\"cmds\">${cmdItems}</div>\n </div>\n ${icpSection}`;\n}\n","import { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { TEST_PREVISUALIZER_STYLES } from './test-previsualizer.styles';\r\nimport { renderTestPrevisualizer } from './test-previsualizer.template';\r\n\r\nexport class TestPrevisualizerElement extends HTMLElement {\r\n private shadow: ShadowRoot\r\n private _commands: string[] = []\r\n private _interceptors: string[] = []\r\n private _showInterceptors = false\r\n editable = false\r\n translation: TranslationService = translationService\r\n\r\n constructor() {\r\n super()\r\n this.shadow = this.attachShadow({ mode: \"open\" })\r\n }\r\n\r\n connectedCallback(): void {\r\n this.render()\r\n }\r\n\r\n get commands(): string[] {\r\n return this._commands\r\n }\r\n set commands(v: string[]) {\r\n this._commands = v\r\n this.render()\r\n }\r\n\r\n get interceptors(): string[] {\r\n return this._interceptors\r\n }\r\n set interceptors(v: string[]) {\r\n this._interceptors = v\r\n this.render()\r\n }\r\n\r\n get showInterceptors(): boolean {\r\n return this._showInterceptors\r\n }\r\n\r\n toggleInterceptors(): void {\r\n this._showInterceptors = !this._showInterceptors\r\n this.render()\r\n }\r\n\r\n copyToClipboard(): void {\r\n const text = this._commands.join(\"\\n\")\r\n if (!text) return\r\n navigator.clipboard?.writeText(text)\r\n }\r\n\r\n copyInterceptorsToClipboard(): void {\r\n const text = this._interceptors.join(\"\\n\")\r\n if (!text) return\r\n navigator.clipboard?.writeText(text)\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key) }\r\n\r\n private dispatchDelete(index: number): void {\r\n this.dispatchEvent(new CustomEvent('deletecommand', { detail: index, bubbles: true, composed: true }))\r\n }\r\n\r\n private dispatchMove(from: number, to: number): void {\r\n this.dispatchEvent(new CustomEvent('movecommand', { detail: { from, to }, bubbles: true, composed: true }))\r\n }\r\n\r\n private dispatchDeleteInterceptor(index: number): void {\r\n this.dispatchEvent(new CustomEvent('deleteinterceptor', { detail: index, bubbles: true, composed: true }))\r\n }\r\n\r\n private render(): void {\r\n this.shadow.innerHTML = `<style>${TEST_PREVISUALIZER_STYLES}</style>${renderTestPrevisualizer(\r\n this._commands,\r\n this._interceptors,\r\n this._showInterceptors,\r\n this.editable,\r\n this.t.bind(this),\r\n )}`;\r\n\r\n const cmdsEl = this.shadow.querySelector<HTMLElement>('[data-ref=\"cmds\"]')\r\n if (cmdsEl) cmdsEl.scrollTop = cmdsEl.scrollHeight\r\n\r\n this.shadow.querySelector('[data-action=\"copy\"]')?.addEventListener(\"click\", () => this.copyToClipboard())\r\n this.shadow.querySelector('[data-action=\"toggle-icp\"]')?.addEventListener(\"click\", () => this.toggleInterceptors())\r\n this.shadow.querySelector('[data-action=\"copy-icp\"]')?.addEventListener(\"click\", () => this.copyInterceptorsToClipboard())\r\n\r\n if (this.editable) {\r\n this.shadow.querySelectorAll('[data-del]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n this.dispatchDelete(Number((btn as HTMLElement).dataset['del']))\r\n })\r\n })\r\n this.shadow.querySelectorAll('[data-move-up]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n const idx = Number((btn as HTMLElement).dataset['moveUp'])\r\n this.dispatchMove(idx, idx - 1)\r\n })\r\n })\r\n this.shadow.querySelectorAll('[data-move-dn]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n const idx = Number((btn as HTMLElement).dataset['moveDn'])\r\n this.dispatchMove(idx, idx + 1)\r\n })\r\n })\r\n this.shadow.querySelectorAll('[data-del-icp]').forEach((btn) => {\r\n btn.addEventListener('click', (e) => {\r\n e.stopPropagation()\r\n this.dispatchDeleteInterceptor(Number((btn as HTMLElement).dataset['delIcp']))\r\n })\r\n })\r\n }\r\n }\r\n}\r\n\r\nif (!customElements.get(\"test-previsualizer\")) {\r\n customElements.define(\"test-previsualizer\", TestPrevisualizerElement)\r\n}\r\n","export const SAVE_TEST_STYLES = `\n :host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }\n * { box-sizing: border-box; }\n .container { padding: 24px 28px; text-align: left; }\n .btn-row, p { text-align: center; }\n p { margin: 0 0 20px; font-size: 14px; color: #8b949e; line-height: 1.5; }\n .btn-row { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 16px; }\n button {\n padding: 7px 16px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; transition: filter 0.15s, transform 0.1s;\n letter-spacing: 0.1px;\n }\n button:hover { filter: brightness(1.1); }\n button:active { transform: scale(0.97); }\n .btn-primary { background: #2f81f7; color: #fff; }\n .btn-success { background: #3fb950; color: #fff; }\n .btn-danger { background: transparent; color: #f85149; border: 1px solid rgba(248,81,73,0.5); }\n .btn-danger:hover { background: rgba(248,81,73,0.08); filter: none; }\n input[type=\"text\"] {\n width: 100%; padding: 10px 14px; border: 1px solid #30363d;\n border-radius: 8px; background: #0d1117; color: #e6edf3;\n font-size: 14px; outline: none; margin-bottom: 4px;\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n input[type=\"text\"]:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.15); }\n input[type=\"text\"]::placeholder { color: #484f58; }\n textarea {\n width: 100%; padding: 10px 14px; border: 1px solid #30363d;\n border-radius: 8px; background: #0d1117; color: #e6edf3;\n font-size: 14px; outline: none; margin-bottom: 4px;\n font-family: inherit; resize: vertical; line-height: 1.5;\n transition: border-color 0.15s, box-shadow 0.15s;\n }\n textarea:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.15); }\n textarea::placeholder { color: #484f58; }\n .tag-label {\n font-size: 11px; color: #484f58; text-align: left; margin-bottom: 5px; display: block;\n }\n .tag-input-row { display: flex; gap: 6px; margin-bottom: 8px; }\n .tag-input-row input[type=\"text\"] {\n font-size: 12px; padding: 6px 10px; margin: 0;\n }\n .btn-tag-add {\n padding: 6px 12px; font-size: 12px; background: #21262d; color: #8b949e;\n border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n transition: background 0.15s, color 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-tag-add:hover { background: #30363d; color: #e6edf3; filter: none; }\n .chips { display: flex; flex-wrap: wrap; gap: 5px; min-height: 24px; text-align: left; }\n .chip {\n display: inline-flex; align-items: center; gap: 5px;\n background: rgba(47,129,247,0.15); color: #2f81f7;\n border: 1px solid rgba(47,129,247,0.3); border-radius: 20px;\n padding: 2px 10px 2px 10px; font-size: 11px; font-weight: 500;\n }\n .chip-del {\n cursor: pointer; color: #8b949e; font-size: 12px; line-height: 1;\n transition: color 0.12s; padding: 0; background: none; border: none;\n }\n .chip-del:hover { color: #f85149; filter: none; }\n`;\n","import { escHtml, escAttr } from '../../utils/html.utils';\n\nexport function renderSaveTestAsk(t: (key: string) => string): string {\n return `\n <div class=\"container\">\n <p>${t('SAVE_TEST.ASK')}</p>\n <div class=\"btn-row\">\n <button class=\"btn-primary\" id=\"btn-yes\">${t('SAVE_TEST.YES_CONTINUE')}</button>\n <button class=\"btn-danger\" id=\"btn-no\">${t('SAVE_TEST.NO_DISCARD')}</button>\n </div>\n </div>`;\n}\n\nexport function renderSaveTestDesc(description: string, notes: string, tags: string[], t: (key: string) => string): string {\n const chipsHtml = tags.map((tag) =>\n `<span class=\"chip\">${escHtml(tag)}<button class=\"chip-del\" data-tag=\"${escAttr(tag)}\" title=\"${t('SAVE_TEST.REMOVE_TAG_TITLE')}\">✕</button></span>`\n ).join('');\n\n return `\n <div class=\"container\">\n <p>${t('SAVE_TEST.DESC_LABEL')} (<code>it()</code>):</p>\n <input id=\"desc-input\" type=\"text\" placeholder=\"${t('SAVE_TEST.DESC_PLACEHOLDER')}\"\n value=\"${escAttr(description)}\" autocomplete=\"off\" />\n <span class=\"tag-label\">${t('SAVE_TEST.NOTES_LABEL')}</span>\n <textarea id=\"notes-input\" rows=\"3\" placeholder=\"${escAttr(t('SAVE_TEST.NOTES_PLACEHOLDER'))}\">${escHtml(notes)}</textarea>\n <span class=\"tag-label\">${t('SAVE_TEST.TAGS_LABEL')}</span>\n <div class=\"tag-input-row\">\n <input id=\"tag-input\" type=\"text\" placeholder=\"${t('SAVE_TEST.TAGS_PLACEHOLDER')}\" autocomplete=\"off\" />\n <button class=\"btn-tag-add\" id=\"btn-add-tag\">${t('SAVE_TEST.ADD_TAG')}</button>\n </div>\n <div class=\"chips\" id=\"chips-container\">${chipsHtml || `<span style=\"color:#484f58;font-size:11px\">${t('SAVE_TEST.NO_TAGS')}</span>`}</div>\n <div class=\"btn-row\">\n <button class=\"btn-primary\" id=\"btn-confirm\">${t('SAVE_TEST.SAVE_BTN')}</button>\n <button class=\"btn-success\" id=\"btn-export\">${t('SAVE_TEST.SAVE_AND_EDIT')}</button>\n <button class=\"btn-danger\" id=\"btn-cancel\">${t('SAVE_TEST.CANCEL')}</button>\n </div>\n </div>`;\n}\n","import { translationService, type TranslationService } from '../../services/translation.service';\nimport { SAVE_TEST_STYLES } from './save-test.styles';\nimport { renderSaveTestAsk, renderSaveTestDesc } from './save-test.template';\n\nexport class SaveTestElement extends HTMLElement {\n private shadow: ShadowRoot;\n private _step: 'ask' | 'desc' = 'ask';\n description = '';\n notes = '';\n tags: string[] = [];\n translation: TranslationService = translationService;\n\n constructor() {\n super();\n this.shadow = this.attachShadow({ mode: 'open' });\n }\n\n connectedCallback(): void { this.render(); }\n\n get step(): 'ask' | 'desc' { return this._step; }\n\n askSave(): void { this._step = 'desc'; this.render(); }\n\n confirmSave(): void { this.dispatch('savetest', { description: this.description.trim(), notes: this.notes, tags: [...this.tags] }); }\n\n confirmSaveAndExport(): void { this.dispatch('saveandexport', { description: this.description.trim(), notes: this.notes, tags: [...this.tags] }); }\n\n cancel(): void { this.dispatch('savetest', { description: null, notes: '', tags: [] }); }\n\n restartComponent(): void { this._step = 'ask'; this.description = ''; this.notes = ''; this.tags = []; this.render(); }\n\n addTag(tag: string): void {\n const t = tag.trim().replace(/[,;]/g, '');\n if (t && !this.tags.includes(t)) {\n this.tags = [...this.tags, t];\n this.render();\n }\n }\n\n removeTag(tag: string): void {\n this.tags = this.tags.filter((t) => t !== tag);\n this.render();\n }\n\n private t(key: string): string { return this.translation.translate(key); }\n\n private dispatch(type: string, detail: { description: string | null; notes: string; tags: string[] }): void {\n this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true }));\n }\n\n private render(): void {\n if (this._step === 'ask') {\n this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestAsk(this.t.bind(this))}`;\n this.shadow.getElementById('btn-yes')?.addEventListener('click', () => this.askSave());\n this.shadow.getElementById('btn-no')?.addEventListener('click', () => this.cancel());\n } else {\n this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestDesc(this.description, this.notes, this.tags, this.t.bind(this))}`;\n\n const descInput = this.shadow.getElementById('desc-input') as HTMLInputElement;\n const notesInput = this.shadow.getElementById('notes-input') as HTMLTextAreaElement;\n const tagInput = this.shadow.getElementById('tag-input') as HTMLInputElement;\n\n descInput.addEventListener('input', () => { this.description = descInput.value; });\n notesInput.addEventListener('input', () => { this.notes = notesInput.value; });\n\n const tryAddTag = () => {\n this.addTag(tagInput.value);\n tagInput.value = '';\n };\n this.shadow.getElementById('btn-add-tag')?.addEventListener('click', tryAddTag);\n tagInput.addEventListener('keydown', (e: KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ',') { e.preventDefault(); tryAddTag(); }\n });\n\n this.shadow.querySelectorAll<HTMLButtonElement>('.chip-del').forEach((btn) => {\n btn.addEventListener('click', () => this.removeTag(btn.dataset['tag'] ?? ''));\n });\n\n this.shadow.getElementById('btn-confirm')?.addEventListener('click', () => this.confirmSave());\n this.shadow.getElementById('btn-export')?.addEventListener('click', () => this.confirmSaveAndExport());\n this.shadow.getElementById('btn-cancel')?.addEventListener('click', () => this.cancel());\n setTimeout(() => descInput.focus(), 60);\n }\n }\n}\n\nif (!customElements.get('save-test')) {\n customElements.define('save-test', SaveTestElement);\n}\n","export const TEST_EDITOR_STYLES = `\n :host { display: flex; flex-direction: column; flex: 1; min-height: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; overflow: hidden; }\n * { box-sizing: border-box; }\n .toolbar {\n display: flex; align-items: center; gap: 6px; padding: 8px 10px; flex-shrink: 0;\n background: #161b22; border-bottom: 1px solid #21262d; flex-wrap: wrap;\n }\n .tag-filter { display: flex; gap: 5px; flex-wrap: wrap; flex: 1; }\n .tag-chip {\n padding: 2px 10px; border-radius: 20px; cursor: pointer; font-size: 11px; font-weight: 500;\n border: 1px solid #30363d; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s, border-color 0.12s;\n }\n .tag-chip:hover { background: #30363d; color: #e6edf3; }\n .tag-chip.active { background: rgba(47,129,247,0.2); color: #2f81f7; border-color: rgba(47,129,247,0.4); }\n .btn-select {\n padding: 4px 12px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 11px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-select:hover { background: #30363d; color: #e6edf3; }\n .btn-select.active { background: rgba(47,129,247,0.15); color: #2f81f7; border-color: rgba(47,129,247,0.3); }\n .describe-bar {\n display: flex; align-items: center; gap: 8px; padding: 8px 10px;\n background: rgba(47,129,247,0.06); border-bottom: 1px solid rgba(47,129,247,0.2);\n flex-wrap: wrap;\n }\n .describe-bar input {\n flex: 1; min-width: 150px; padding: 5px 10px; background: #0d1117;\n border: 1px solid #30363d; border-radius: 6px; color: #e6edf3;\n font-size: 12px; outline: none;\n }\n .describe-bar input:focus { border-color: #2f81f7; }\n .btn-gen-describe {\n padding: 5px 14px; border: 1px solid #2f81f7; border-radius: 6px; cursor: pointer;\n font-size: 11px; font-weight: 500; background: rgba(47,129,247,0.15); color: #2f81f7;\n transition: background 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-gen-describe:hover { background: rgba(47,129,247,0.25); }\n .selected-count { font-size: 11px; color: #8b949e; }\n .describe-bar { flex-shrink: 0; }\n .list { padding: 8px; flex: 1; min-height: 0; overflow-y: auto;\n scrollbar-width: thin; scrollbar-color: #30363d transparent; }\n .list::-webkit-scrollbar { width: 4px; }\n .list::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .empty { color: #484f58; text-align: center; padding: 32px; font-size: 13px; }\n .row {\n background: #0d1117; border-radius: 8px; margin-bottom: 6px;\n overflow: hidden; border: 1px solid #21262d;\n transition: border-color 0.15s;\n }\n .row:hover { border-color: #30363d; }\n .row.selected-row { border-color: rgba(47,129,247,0.5); }\n .row-header {\n display: flex; align-items: center; gap: 8px;\n padding: 10px 12px; cursor: pointer; user-select: none;\n }\n .row-header:hover { background: rgba(48,54,61,0.3); }\n .test-name { flex: 1; font-size: 13px; font-weight: 500; color: #e6edf3; }\n .test-date { font-size: 10.5px; color: #484f58; margin-right: 4px; }\n .test-tags { display: flex; gap: 4px; margin-right: 4px; }\n .test-tag {\n padding: 1px 7px; border-radius: 20px; font-size: 10px;\n background: rgba(47,129,247,0.1); color: #8b949e; border: 1px solid rgba(47,129,247,0.2);\n }\n .btn-icon {\n padding: 3px 8px; border: none; border-radius: 6px; cursor: pointer;\n font-size: 11px; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s;\n }\n .btn-icon:hover { background: #30363d; color: #e6edf3; }\n .btn-del:hover { background: rgba(248,81,73,0.15); color: #f85149; }\n input[type=\"checkbox\"] {\n width: 14px; height: 14px; accent-color: #2f81f7; cursor: pointer; flex-shrink: 0;\n }\n .row-body {\n background: #0d1117; padding: 10px 14px;\n border-top: 1px solid #21262d;\n }\n .test-notes {\n margin: 0 0 10px; padding: 8px 12px;\n background: rgba(47,129,247,0.06); border-left: 3px solid rgba(47,129,247,0.4);\n border-radius: 0 6px 6px 0; font-size: 12px; color: #8b949e;\n line-height: 1.6; white-space: pre-wrap; word-break: break-word;\n }\n .code-preview {\n margin: 0; padding: 10px 12px; background: #161b22;\n border-radius: 6px; border: 1px solid #21262d;\n font-size: 11px; color: #c9d1d9; line-height: 1.7;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n overflow-x: auto; white-space: pre;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .code-preview::-webkit-scrollbar { height: 4px; }\n .code-preview::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .code-preview-icp { margin-top: 8px; }\n .sh-kw { color: #ff7b72; }\n .sh-bi { color: #d2a8ff; }\n .sh-str { color: #a5d6ff; }\n .sh-cmt { color: #8b949e; font-style: italic; }\n .sh-num { color: #79c0ff; }\n`;\n","import { escHtml } from './html.utils';\n\nconst KEYWORDS = new Set([\n 'describe', 'it', 'xit', 'fit', 'xdescribe', 'fdescribe',\n 'beforeEach', 'afterEach', 'before', 'after', 'context',\n 'const', 'let', 'var', 'function', 'return', 'if', 'else',\n 'import', 'export', 'from', 'new', 'this', 'null', 'undefined',\n 'true', 'false', 'async', 'await', 'of', 'in', 'typeof', 'void',\n]);\n\nconst BUILTINS = new Set(['cy', 'expect', 'assert', 'Cypress', 'chai']);\n\nexport function syntaxHighlight(code: string): string {\n return code.split('\\n').map(highlightLine).join('\\n');\n}\n\nfunction highlightLine(line: string): string {\n let result = '';\n let i = 0;\n const len = line.length;\n\n while (i < len) {\n // Single-line comment\n if (line[i] === '/' && i + 1 < len && line[i + 1] === '/') {\n result += `<span class=\"sh-cmt\">${escHtml(line.slice(i))}</span>`;\n return result;\n }\n // String literal (single, double, or template)\n const q = line[i];\n if (q === \"'\" || q === '\"' || q === '`') {\n let j = i + 1;\n while (j < len) {\n if (line[j] === '\\\\') { j += 2; continue; }\n if (line[j] === q) { j++; break; }\n j++;\n }\n result += `<span class=\"sh-str\">${escHtml(line.slice(i, j))}</span>`;\n i = j;\n continue;\n }\n // Number (not preceded by identifier character)\n if (/[0-9]/.test(line[i]) && (i === 0 || !/[a-zA-Z_$]/.test(line[i - 1]))) {\n let j = i;\n while (j < len && /[0-9.]/.test(line[j])) j++;\n result += `<span class=\"sh-num\">${escHtml(line.slice(i, j))}</span>`;\n i = j;\n continue;\n }\n // Identifier, keyword, or builtin\n if (/[a-zA-Z_$]/.test(line[i])) {\n let j = i;\n while (j < len && /[a-zA-Z0-9_$]/.test(line[j])) j++;\n const word = line.slice(i, j);\n if (KEYWORDS.has(word)) {\n result += `<span class=\"sh-kw\">${escHtml(word)}</span>`;\n } else if (BUILTINS.has(word)) {\n result += `<span class=\"sh-bi\">${escHtml(word)}</span>`;\n } else {\n result += escHtml(word);\n }\n i = j;\n continue;\n }\n result += escHtml(line[i]);\n i++;\n }\n return result;\n}\n","import { escHtml, escAttr } from '../../utils/html.utils';\nimport { syntaxHighlight } from '../../utils/syntax-highlight.utils';\nimport { normalizeBlock } from '../../utils/code-format.utils';\nimport type { TestWithDetails } from '../../services/persistence.service';\n\nexport interface TestEditorState {\n tags: string[];\n visible: TestWithDetails[];\n selectedVisible: TestWithDetails[];\n activeTag: string | null;\n selectMode: boolean;\n selectedIds: Set<number>;\n describeName: string;\n expandedIndex: number | null;\n interceptorsByTest: Record<number, string[]>;\n}\n\nexport function renderTestEditor(state: TestEditorState, t: (key: string) => string): string {\n const { tags, visible, selectedVisible, activeTag, selectMode, selectedIds, describeName, expandedIndex, interceptorsByTest } = state;\n\n const tagFilterHtml = tags.length\n ? `<div class=\"tag-filter\">\n ${tags.map((tag) => `<button class=\"tag-chip${activeTag === tag ? ' active' : ''}\" data-filter-tag=\"${escAttr(tag)}\">${escHtml(tag)}</button>`).join('')}\n </div>`\n : `<div class=\"tag-filter\" style=\"color:#484f58;font-size:11px\">${t('TEST_EDITOR.NO_TAGS')}</div>`;\n\n const describeBarHtml = selectMode && selectedVisible.length > 0\n ? `<div class=\"describe-bar\">\n <span class=\"selected-count\">${selectedVisible.length} ${selectedVisible.length !== 1 ? t('TEST_EDITOR.SELECTED_PLURAL') : t('TEST_EDITOR.SELECTED_SINGULAR')}</span>\n <input id=\"describe-name\" type=\"text\" placeholder=\"${t('TEST_EDITOR.DESCRIBE_PLACEHOLDER')}\" value=\"${escAttr(describeName)}\" />\n <button class=\"btn-gen-describe\" id=\"btn-gen-describe\">${t('TEST_EDITOR.COPY_DESCRIBE')}</button>\n </div>`\n : '';\n\n const rows = visible.map((test, i) => {\n const expanded = expandedIndex === i;\n const date = new Date(test.createdAt).toLocaleString('es-ES', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });\n const icps = interceptorsByTest[test.id] ?? test.interceptors ?? [];\n const tagsHtml = (test.tags ?? []).length\n ? `<span class=\"test-tags\">${(test.tags ?? []).map((tag) => `<span class=\"test-tag\">${escHtml(tag)}</span>`).join('')}</span>`\n : '';\n const checkbox = selectMode\n ? `<input type=\"checkbox\" ${selectedIds.has(test.id) ? 'checked' : ''} data-select=\"${test.id}\" />`\n : '';\n const hasIcps = (test.interceptors ?? []).length > 0;\n const itBlockCode = `it('${test.name}', () => {\\n${(test.commands ?? []).map(c => normalizeBlock(c, ' ')).join('\\n')}\\n});`;\n const icpBlockCode = icps.length ? `beforeEach(() => {\\n // Auto-generated Cypress interceptors\\n${icps.map(c => normalizeBlock(c, ' ')).join('\\n')}\\n});` : '';\n const notesHtml = (expanded && test.notes)\n ? `<p class=\"test-notes\">${escHtml(test.notes)}</p>`\n : '';\n const body = expanded ? `\n <div class=\"row-body\">\n ${notesHtml}\n <pre class=\"code-preview\">${syntaxHighlight(itBlockCode)}</pre>\n ${icpBlockCode ? `<pre class=\"code-preview code-preview-icp\">${syntaxHighlight(icpBlockCode)}</pre>` : ''}\n </div>` : '';\n return `\n <div class=\"row${selectedIds.has(test.id) ? ' selected-row' : ''}\">\n <div class=\"row-header\" data-action=\"expand\" data-idx=\"${i}\">\n ${checkbox}\n <span class=\"test-name\">${escHtml(test.name)}</span>\n ${tagsHtml}\n <span class=\"test-date\">${date}</span>\n <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>\n ${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>` : ''}\n <button class=\"btn-icon btn-del\" data-action=\"delete\" data-id=\"${test.id}\" title=\"${t('TEST_EDITOR.DELETE_TITLE')}\">🗑</button>\n </div>\n ${body}\n </div>`;\n }).join('');\n\n return `\n <div class=\"toolbar\">\n ${tagFilterHtml}\n <button class=\"btn-select${selectMode ? ' active' : ''}\" id=\"btn-select-mode\">\n ${selectMode ? t('TEST_EDITOR.CANCEL_SELECT') : t('TEST_EDITOR.MULTI_SELECT')}\n </button>\n </div>\n ${describeBarHtml}\n <div class=\"list\">\n ${visible.length ? rows : `<div class=\"empty\">${t('TEST_EDITOR.NO_TESTS')}</div>`}\n </div>`;\n}\n","import { PersistenceService } from '../../services/persistence.service';\r\nimport type { TestWithDetails } from '../../services/persistence.service';\r\nimport { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { TEST_EDITOR_STYLES } from './test-editor.styles';\r\nimport { renderTestEditor } from './test-editor.template';\r\n\r\nexport class TestEditorElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n persistence!: PersistenceService;\r\n translation: TranslationService = translationService;\r\n tests: TestWithDetails[] = [];\r\n expandedIndex: number | null = null;\r\n interceptorsByTest: Record<number, string[]> = {};\r\n activeTag: string | null = null;\r\n selectMode = false;\r\n selectedIds: Set<number> = new Set();\r\n describeName = '';\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.persistence) this.persistence = new PersistenceService();\r\n this.loadTests();\r\n }\r\n\r\n async loadTests(): Promise<void> {\r\n this.tests = await this.persistence.getAllTests();\r\n this.render();\r\n }\r\n\r\n async deleteTest(id: number): Promise<void> {\r\n await this.persistence.deleteTest(id);\r\n this.selectedIds.delete(id);\r\n await this.loadTests();\r\n }\r\n\r\n toggleExpand(index: number): void {\r\n this.expandedIndex = this.expandedIndex === index ? null : index;\r\n if (this.expandedIndex !== null) {\r\n const test = this.tests[this.expandedIndex];\r\n if (test?.id && !this.interceptorsByTest[test.id]) {\r\n this.interceptorsByTest[test.id] = Array.isArray(test.interceptors) ? test.interceptors : [];\r\n }\r\n }\r\n this.render();\r\n }\r\n\r\n hasInterceptors(testId: number): boolean {\r\n return Array.isArray(this.interceptorsByTest[testId]) && this.interceptorsByTest[testId].length > 0;\r\n }\r\n\r\n toggleSelectMode(): void {\r\n this.selectMode = !this.selectMode;\r\n if (!this.selectMode) this.selectedIds.clear();\r\n this.render();\r\n }\r\n\r\n toggleSelectTest(id: number): void {\r\n if (this.selectedIds.has(id)) this.selectedIds.delete(id);\r\n else this.selectedIds.add(id);\r\n this.render();\r\n }\r\n\r\n generateDescribe(): void {\r\n const selected = this.tests.filter((t) => this.selectedIds.has(t.id));\r\n if (!selected.length) return;\r\n\r\n const name = this.describeName.trim() || this.t('TEST_EDITOR.DEFAULT_DESCRIBE');\r\n\r\n const allInterceptors = [...new Set(\r\n selected.flatMap((t) => this.interceptorsByTest[t.id] ?? t.interceptors ?? [])\r\n )];\r\n\r\n const beforeEach = allInterceptors.length\r\n ? ` beforeEach(() => {\\n // Auto-generated Cypress interceptors\\n ${allInterceptors.join('\\n ')}\\n });\\n\\n`\r\n : '';\r\n\r\n const itBlocks = selected\r\n .map((t) => {\r\n const cmds = (t.commands ?? []).map((c) => ` ${c}`).join('\\n');\r\n return ` it('${(t.name ?? '').replace(/'/g, \"\\\\'\")}', () => {\\n${cmds}\\n });`;\r\n })\r\n .join('\\n\\n');\r\n\r\n const block = `describe('${name.replace(/'/g, \"\\\\'\")}', () => {\\n${beforeEach}${itBlocks}\\n});`;\r\n navigator.clipboard?.writeText(block);\r\n }\r\n\r\n copyToClipboard(text: string): void {\r\n navigator.clipboard?.writeText(text);\r\n }\r\n\r\n get allTags(): string[] {\r\n const tagSet = new Set<string>();\r\n this.tests.forEach((t) => (t.tags ?? []).forEach((tag) => tagSet.add(tag)));\r\n return [...tagSet].sort();\r\n }\r\n\r\n get visibleTests(): TestWithDetails[] {\r\n const tag = this.activeTag;\r\n if (!tag) return this.tests;\r\n return this.tests.filter((t) => (t.tags ?? []).includes(tag));\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private render(): void {\r\n const tags = this.allTags;\r\n const visible = this.visibleTests;\r\n const selectedVisible = visible.filter((t) => this.selectedIds.has(t.id));\r\n\r\n this.shadow.innerHTML = `<style>${TEST_EDITOR_STYLES}</style>${renderTestEditor({\r\n tags,\r\n visible,\r\n selectedVisible,\r\n activeTag: this.activeTag,\r\n selectMode: this.selectMode,\r\n selectedIds: this.selectedIds,\r\n describeName: this.describeName,\r\n expandedIndex: this.expandedIndex,\r\n interceptorsByTest: this.interceptorsByTest,\r\n }, this.t.bind(this))}`;\r\n\r\n this.shadow.getElementById('btn-select-mode')?.addEventListener('click', () => this.toggleSelectMode());\r\n\r\n this.shadow.querySelectorAll('[data-filter-tag]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n const tag = (el as HTMLElement).dataset['filterTag'] ?? '';\r\n if (!tag) return;\r\n this.activeTag = this.activeTag === tag ? null : tag;\r\n this.render();\r\n });\r\n });\r\n\r\n const descInput = this.shadow.getElementById('describe-name') as HTMLInputElement | null;\r\n if (descInput) {\r\n descInput.addEventListener('input', () => { this.describeName = descInput.value; });\r\n }\r\n this.shadow.getElementById('btn-gen-describe')?.addEventListener('click', () => {\r\n this.describeName = descInput?.value ?? this.describeName;\r\n this.generateDescribe();\r\n });\r\n\r\n this.shadow.querySelectorAll('[data-select]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n this.toggleSelectTest(Number((el as HTMLElement).dataset['select']));\r\n });\r\n });\r\n\r\n this.shadow.querySelectorAll('[data-action=\"expand\"]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n if (this.selectMode) {\r\n const row = visible[Number((el as HTMLElement).dataset['idx'])];\r\n if (row) this.toggleSelectTest(row.id);\r\n } else {\r\n this.toggleExpand(Number((el as HTMLElement).dataset['idx']));\r\n }\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-action=\"delete\"]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n this.deleteTest(Number((el as HTMLElement).dataset['id']));\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-action=\"copy-cmds\"]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n const idx = Number((el as HTMLElement).dataset['idx']);\r\n this.copyToClipboard((visible[idx]?.commands ?? []).join('\\n'));\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-action=\"copy-icps\"]').forEach((el) => {\r\n el.addEventListener('click', (ev) => {\r\n ev.stopPropagation();\r\n const idx = Number((el as HTMLElement).dataset['idx']);\r\n const t = visible[idx];\r\n this.copyToClipboard((this.interceptorsByTest[t?.id] ?? t?.interceptors ?? []).join('\\n'));\r\n });\r\n });\r\n }\r\n}\r\n\r\nif (!customElements.get('test-editor')) {\r\n customElements.define('test-editor', TestEditorElement);\r\n}\r\n","export const CONFIGURATION_STYLES = `\n :host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }\n * { box-sizing: border-box; }\n\n /* ── Grid container ───────────────────────────────────── */\n .cfg-grid {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n padding: 14px;\n }\n\n /* ── Cards ────────────────────────────────────────────── */\n .card {\n background: #161b22;\n border: 1px solid #21262d;\n border-radius: 10px;\n padding: 14px 16px;\n transition: border-color 0.15s;\n }\n .card:hover { border-color: #30363d; }\n .card-wide { grid-column: 1 / -1; }\n\n /* ── Card header ──────────────────────────────────────── */\n .card-hd {\n display: flex; align-items: center; gap: 7px;\n font-size: 10px; font-weight: 700; text-transform: uppercase;\n letter-spacing: 0.8px; color: #484f58; margin-bottom: 12px;\n }\n .card-hd-icon { font-size: 13px; }\n\n /* ── Language ─────────────────────────────────────────── */\n .field-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }\n .field-label { font-size: 12px; color: #8b949e; }\n select {\n background: #0d1117; color: #e6edf3; border: 1px solid #30363d;\n border-radius: 6px; padding: 6px 10px; font-size: 12px; outline: none;\n cursor: pointer; transition: border-color 0.15s; flex-shrink: 0;\n }\n select:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.12); }\n\n /* ── HTTP toggle ──────────────────────────────────────── */\n .check-row {\n display: flex; align-items: flex-start; gap: 10px;\n cursor: pointer; user-select: none;\n }\n input[type=\"checkbox\"] { width: 15px; height: 15px; margin-top: 2px; cursor: pointer; accent-color: #2f81f7; flex-shrink: 0; }\n .check-title { font-size: 12px; color: #c9d1d9; margin-bottom: 3px; }\n .check-sub { font-size: 10px; color: #484f58; line-height: 1.5; }\n\n /* ── Cypress folder ───────────────────────────────────── */\n .fs-layout { display: flex; gap: 12px; align-items: flex-start; }\n .fs-tree {\n flex-shrink: 0;\n margin: 0; padding: 8px 10px;\n background: #0d1117; border: 1px solid #21262d; border-radius: 6px;\n font-size: 10px; color: #c9d1d9; line-height: 1.8;\n font-family: 'Cascadia Code','Fira Code','Consolas',monospace;\n }\n .fs-right { display: flex; flex-direction: column; gap: 10px; flex: 1; }\n .fs-status {\n display: flex; align-items: center; gap: 8px;\n font-size: 12px; color: #8b949e;\n background: #0d1117; border: 1px solid #21262d; border-radius: 6px;\n padding: 8px 10px;\n }\n .fs-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }\n .fs-dot.on { background: #3fb950; box-shadow: 0 0 6px rgba(63,185,80,.5); }\n .fs-dot.off { background: #484f58; }\n .fs-folder { color: #e6edf3; font-family: 'Cascadia Code','Fira Code','Consolas',monospace; font-size: 11px; }\n\n /* ── Buttons ──────────────────────────────────────────── */\n .btn-row { display: flex; gap: 8px; flex-wrap: wrap; }\n button {\n padding: 7px 14px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s, border-color 0.15s;\n }\n button:hover { background: #30363d; color: #e6edf3; border-color: #484f58; }\n .btn-import {\n display: inline-block;\n padding: 7px 14px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s, border-color 0.15s;\n }\n .btn-import:hover { background: #30363d; color: #e6edf3; border-color: #484f58; }\n .btn-danger { border-color: rgba(248,81,73,.4); color: #f85149; background: transparent; }\n .btn-danger:hover { background: rgba(248,81,73,.08); border-color: #f85149; color: #f85149; }\n .file-input { display: none; }\n\n /* ── Data section desc ────────────────────────────────── */\n .data-desc { font-size: 11px; color: #484f58; margin-bottom: 10px; line-height: 1.5; }\n`;\n","export const LANGS = [\n { value: 'es', label: 'Español' },\n { value: 'en', label: 'English' },\n { value: 'fr', label: 'Français' },\n { value: 'it', label: 'Italiano' },\n { value: 'de', label: 'Deutsch' },\n];\n\nexport interface ConfigurationState {\n selectedLanguage: string;\n advancedHttpConfig: boolean;\n selectorStrategy: string;\n filesystemGranted: boolean;\n cypressFolderName: string | null;\n smartSelectorEnabled: boolean;\n startHidden: boolean;\n}\n\nexport function renderConfiguration(state: ConfigurationState, t: (key: string) => string): string {\n const { selectedLanguage, advancedHttpConfig, selectorStrategy, filesystemGranted, cypressFolderName, smartSelectorEnabled, startHidden } = state;\n\n const langOptions = LANGS.map(\n (l) => `<option value=\"${l.value}\" ${selectedLanguage === l.value ? 'selected' : ''}>${l.label}</option>`,\n ).join('');\n\n return `\n <div class=\"cfg-grid\">\n\n <!-- Language -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.LANG_SECTION')}</div>\n <div class=\"field-row\">\n <span class=\"field-label\">${t('CONFIG.LANG_FIELD')}</span>\n <select id=\"lang-select\">${langOptions}</select>\n </div>\n </div>\n\n <!-- HTTP Advanced -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.HTTP_SECTION')}</div>\n <label class=\"check-row\">\n <input type=\"checkbox\" id=\"http-toggle\" ${advancedHttpConfig ? 'checked' : ''} />\n <div>\n <div class=\"check-title\">${t('CONFIG.HTTP_TITLE')}</div>\n <div class=\"check-sub\">${t('CONFIG.HTTP_SUB')}</div>\n </div>\n </label>\n </div>\n\n <!-- Smart Selector -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.SMART_SELECTOR_SECTION')}</div>\n <label class=\"check-row\">\n <input type=\"checkbox\" id=\"smart-selector-toggle\" ${smartSelectorEnabled ? 'checked' : ''} />\n <div>\n <div class=\"check-title\">${t('CONFIG.SMART_SELECTOR_TITLE')}</div>\n <div class=\"check-sub\">${t('CONFIG.SMART_SELECTOR_SUB')}</div>\n </div>\n </label>\n </div>\n\n <!-- Start Hidden -->\n <div class=\"card\">\n <div class=\"card-hd\">${t('CONFIG.START_HIDDEN_SECTION')}</div>\n <label class=\"check-row\">\n <input type=\"checkbox\" id=\"start-hidden-toggle\" ${startHidden ? 'checked' : ''} />\n <div>\n <div class=\"check-title\">${t('CONFIG.START_HIDDEN_TITLE')}</div>\n <div class=\"check-sub\">${t('CONFIG.START_HIDDEN_SUB')}</div>\n </div>\n </label>\n </div>\n\n <!-- Selector Strategy -->\n <div class=\"card card-wide\">\n <div class=\"card-hd\">${t('CONFIG.SELECTOR_SECTION')}</div>\n <div class=\"field-row\">\n <span class=\"field-label\">${t('CONFIG.SELECTOR_LABEL')}</span>\n <select id=\"selector-strategy\">\n <option value=\"data-cy\" ${selectorStrategy === 'data-cy' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_DATACY')}</option>\n <option value=\"data-testid\" ${selectorStrategy === 'data-testid' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_TESTID')}</option>\n <option value=\"aria-label\" ${selectorStrategy === 'aria-label' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_ARIA')}</option>\n <option value=\"id\" ${selectorStrategy === 'id' ? 'selected' : ''}>${t('CONFIG.SELECTOR_OPT_ID')}</option>\n </select>\n </div>\n <div class=\"check-sub\" style=\"margin-top:8px\">${t('CONFIG.SELECTOR_HINT')}</div>\n </div>\n\n <!-- Cypress Folder -->\n <div class=\"card card-wide\">\n <div class=\"card-hd\">${t('CONFIG.FOLDER_SECTION')}</div>\n <div class=\"fs-layout\">\n <pre class=\"fs-tree\">cypress/ <span style=\"color:#484f58\">← selecciona</span>\n└── e2e/\n └── *.cy.ts</pre>\n <div class=\"fs-right\">\n <div class=\"fs-status\">\n <span class=\"fs-dot ${filesystemGranted ? 'on' : 'off'}\"></span>\n ${filesystemGranted && cypressFolderName\n ? `<span>${t('CONFIG.FOLDER_CONNECTED')}</span>&nbsp;<span class=\"fs-folder\">📁 ${cypressFolderName}</span>`\n : `<span>${t('CONFIG.FOLDER_NOT_SET')}</span>`}\n </div>\n <div class=\"btn-row\">\n <button id=\"btn-change-folder\">\n ${filesystemGranted ? t('CONFIG.FOLDER_CHANGE_BTN') : t('CONFIG.FOLDER_SELECT_BTN')}\n </button>\n ${filesystemGranted\n ? `<button id=\"btn-revoke\" class=\"btn-danger\">${t('CONFIG.FOLDER_REVOKE_BTN')}</button>`\n : ''}\n </div>\n </div>\n </div>\n </div>\n\n <!-- Data -->\n <div class=\"card card-wide\">\n <div class=\"card-hd\">${t('CONFIG.DATA_SECTION')}</div>\n <p class=\"data-desc\">${t('CONFIG.DATA_DESC')}</p>\n <div class=\"btn-row\">\n <button id=\"btn-export\">${t('CONFIG.EXPORT_BTN')}</button>\n <label style=\"cursor:pointer;margin:0\">\n <span class=\"btn-import\">${t('CONFIG.IMPORT_BTN')}</span>\n <input type=\"file\" class=\"file-input\" id=\"file-input\" accept=\".json\" />\n </label>\n </div>\n </div>\n\n </div>`;\n}\n","import { PersistenceService } from \"../../services/persistence.service\"\r\nimport { TranslationService } from \"../../services/translation.service\"\r\nimport type { Lang } from \"../../models/lang.model\"\r\nimport type { SelectorStrategy } from \"../../services/recording.service\"\r\nimport { showToast } from \"../../utils/toast.utils\"\r\nimport { CONFIGURATION_STYLES } from './configuration.styles';\r\nimport { renderConfiguration } from './configuration.template';\r\n\r\nexport class ConfigurationElement extends HTMLElement {\r\n private shadow: ShadowRoot\r\n persistence!: PersistenceService\r\n translation!: TranslationService\r\n selectedLanguage = \"es\"\r\n advancedHttpConfig = false\r\n selectorStrategy: SelectorStrategy = 'data-cy'\r\n smartSelectorEnabled = true\r\n startHidden = false\r\n private filesystemGranted = false\r\n private cypressFolderName: string | null = null\r\n\r\n constructor() {\r\n super()\r\n this.shadow = this.attachShadow({ mode: \"open\" })\r\n this.advancedHttpConfig = localStorage.getItem(\"extendedHttpCommands\") === \"true\"\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.persistence) this.persistence = new PersistenceService()\r\n if (!this.translation) this.translation = new TranslationService()\r\n this.loadConfig()\r\n this.render()\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private async loadConfig(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig()\r\n if (config?.['language']) {\r\n this.selectedLanguage = config['language'] as string\r\n this.translation.setLang(this.selectedLanguage as Lang)\r\n }\r\n this.advancedHttpConfig = localStorage.getItem(\"extendedHttpCommands\") === \"true\"\r\n this.selectorStrategy = (config?.['selectorStrategy'] as SelectorStrategy) ?? 'data-cy'\r\n this.smartSelectorEnabled = config?.['smartSelectorEnabled'] !== 'false'\r\n this.startHidden = config?.['startHidden'] === 'true'\r\n this.filesystemGranted = config?.['allowReadWriteFiles'] === 'true'\r\n const handle = config?.['cypressDirectoryHandle'] as FileSystemDirectoryHandle | undefined\r\n this.cypressFolderName = handle?.name ?? null\r\n this.render()\r\n }\r\n\r\n async onLanguageChange(lang: string): Promise<void> {\r\n this.selectedLanguage = lang\r\n this.translation.setLang(lang as Lang)\r\n await this.persistence.setConfig({ language: lang })\r\n this.render()\r\n }\r\n\r\n onAdvancedHttpConfigChange(checked: boolean): void {\r\n this.advancedHttpConfig = checked\r\n localStorage.setItem(\"extendedHttpCommands\", checked ? \"true\" : \"false\")\r\n this.persistence.setConfig({ extendedHttpCommands: checked ? \"true\" : \"false\" })\r\n this.render()\r\n }\r\n\r\n async onStartHiddenChange(checked: boolean): Promise<void> {\r\n this.startHidden = checked\r\n await this.persistence.setConfig({ startHidden: checked ? 'true' : 'false' })\r\n this.dispatchEvent(new CustomEvent('starthiddenchange', { detail: checked, bubbles: true, composed: true }))\r\n this.render()\r\n }\r\n\r\n async onSmartSelectorChange(enabled: boolean): Promise<void> {\r\n this.smartSelectorEnabled = enabled\r\n await this.persistence.setConfig({ smartSelectorEnabled: enabled ? 'true' : 'false' })\r\n this.dispatchEvent(new CustomEvent('smartselectorchange', { detail: enabled, bubbles: true, composed: true }))\r\n this.render()\r\n }\r\n\r\n async onSelectorStrategyChange(strategy: SelectorStrategy): Promise<void> {\r\n this.selectorStrategy = strategy\r\n await this.persistence.setConfig({ selectorStrategy: strategy })\r\n this.dispatchEvent(new CustomEvent('selectorstrategychange', { detail: strategy, bubbles: true, composed: true }))\r\n this.render()\r\n }\r\n\r\n async changeFolder(): Promise<void> {\r\n try {\r\n await this.persistence.requestDirectoryPermissions()\r\n await this.loadConfig()\r\n showToast(this.t('CONFIG.FOLDER_UPDATED_TOAST'))\r\n } catch (e: unknown) {\r\n if ((e as DOMException)?.name !== 'AbortError') {\r\n showToast(this.t('CONFIG.FOLDER_ERROR_TOAST'), false)\r\n }\r\n }\r\n }\r\n\r\n async revokeAccess(): Promise<void> {\r\n await this.persistence.setConfig({ allowReadWriteFiles: 'false', cypressDirectoryHandle: null })\r\n this.filesystemGranted = false\r\n this.cypressFolderName = null\r\n this.render()\r\n }\r\n\r\n async exportAllData(): Promise<void> {\r\n const tests = await this.persistence.getAllTests()\r\n const blob = new Blob([JSON.stringify({ tests, interceptors: [] }, null, 2)], { type: \"application/json\" })\r\n const url = URL.createObjectURL(blob)\r\n const a = document.createElement(\"a\")\r\n a.href = url\r\n a.download = \"e2e-cypress-export.json\"\r\n a.click()\r\n URL.revokeObjectURL(url)\r\n }\r\n\r\n async importAllData(file: File): Promise<void> {\r\n const text = await file.text()\r\n let data: { tests: Record<string, unknown>[]; interceptors: Record<string, unknown>[] }\r\n try {\r\n data = JSON.parse(text)\r\n } catch {\r\n throw new Error(this.t('CONFIG.JSON_INVALID'))\r\n }\r\n if (!data || !Array.isArray(data.tests) || !Array.isArray(data.interceptors)) {\r\n throw new Error(this.t('CONFIG.JSON_BAD_FORMAT'))\r\n }\r\n await this.persistence.clearAllData()\r\n await this.persistence.ingestFileData(data.tests, data.interceptors)\r\n }\r\n\r\n private render(): void {\r\n this.shadow.innerHTML = `<style>${CONFIGURATION_STYLES}</style>${renderConfiguration({\r\n selectedLanguage: this.selectedLanguage,\r\n advancedHttpConfig: this.advancedHttpConfig,\r\n selectorStrategy: this.selectorStrategy,\r\n filesystemGranted: this.filesystemGranted,\r\n cypressFolderName: this.cypressFolderName,\r\n smartSelectorEnabled: this.smartSelectorEnabled,\r\n startHidden: this.startHidden,\r\n }, this.t.bind(this))}`;\r\n ;(this.shadow.getElementById(\"lang-select\") as HTMLSelectElement).addEventListener(\"change\", (e) =>\r\n this.onLanguageChange((e.target as HTMLSelectElement).value),\r\n )\r\n ;(this.shadow.getElementById(\"http-toggle\") as HTMLInputElement).addEventListener(\"change\", (e) =>\r\n this.onAdvancedHttpConfigChange((e.target as HTMLInputElement).checked),\r\n )\r\n ;(this.shadow.getElementById(\"smart-selector-toggle\") as HTMLInputElement).addEventListener(\"change\", (e) =>\r\n this.onSmartSelectorChange((e.target as HTMLInputElement).checked),\r\n )\r\n ;(this.shadow.getElementById(\"start-hidden-toggle\") as HTMLInputElement).addEventListener(\"change\", (e) =>\r\n this.onStartHiddenChange((e.target as HTMLInputElement).checked),\r\n )\r\n ;(this.shadow.getElementById(\"selector-strategy\") as HTMLSelectElement).addEventListener(\"change\", (e) =>\r\n this.onSelectorStrategyChange((e.target as HTMLSelectElement).value as SelectorStrategy),\r\n )\r\n\r\n this.shadow.getElementById(\"btn-change-folder\")?.addEventListener(\"click\", () => this.changeFolder())\r\n this.shadow.getElementById(\"btn-revoke\")?.addEventListener(\"click\", () => this.revokeAccess())\r\n this.shadow.getElementById(\"btn-export\")?.addEventListener(\"click\", () => this.exportAllData())\r\n ;(this.shadow.getElementById(\"file-input\") as HTMLInputElement).addEventListener(\"change\", async (e) => {\r\n const file = (e.target as HTMLInputElement).files?.[0]\r\n if (!file) return\r\n try {\r\n await this.importAllData(file)\r\n alert(this.t('CONFIG.IMPORT_SUCCESS'))\r\n } catch (err: unknown) {\r\n alert((err as Error).message ?? this.t('CONFIG.IMPORT_ERROR'))\r\n }\r\n const target = e.target as HTMLInputElement | null\r\n if (target) target.value = ''\r\n })\r\n }\r\n}\r\n\r\nif (!customElements.get(\"e2e-configuration\")) {\r\n customElements.define(\"e2e-configuration\", ConfigurationElement)\r\n}\r\n","export const ADVANCED_TEST_EDITOR_STYLES = `\n :host { display: flex; flex-direction: column; flex: 1; min-height: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; overflow: hidden; }\n * { box-sizing: border-box; }\n .layout { display: flex; flex: 1; min-height: 0; }\n .sidebar {\n border-right: none; display: flex; flex-direction: column;\n background: #0d1117; flex-shrink: 0; min-width: 140px; max-width: 500px;\n }\n .tree-scroll {\n flex: 1; overflow-y: auto; padding: 6px 4px;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .tree-scroll::-webkit-scrollbar { width: 4px; }\n .tree-scroll::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .resize-handle {\n width: 4px; background: #21262d; cursor: col-resize; flex-shrink: 0;\n transition: background 0.15s;\n }\n .resize-handle:hover, .resize-handle.dragging { background: #2f81f7; }\n .main { flex: 1; display: flex; flex-direction: column; overflow: hidden; background: #161b22; min-width: 0; }\n .no-perm {\n padding: 28px; color: #484f58; font-size: 13px; text-align: center;\n display: flex; flex-direction: column; align-items: center; gap: 12px; line-height: 1.6;\n }\n .tree-item {\n padding: 4px 6px; border-radius: 4px; cursor: pointer;\n font-size: 12px; color: #8b949e; white-space: nowrap;\n overflow: hidden; text-overflow: ellipsis;\n transition: background 0.12s, color 0.12s;\n display: flex; align-items: center; gap: 4px; user-select: none;\n }\n .tree-item:hover { background: #161b22; color: #c9d1d9; }\n .tree-item.selected { background: rgba(47,129,247,0.12); color: #2f81f7; }\n .tree-item.dir { color: #e3b341; font-weight: 600; }\n .tree-item.dir:hover { background: rgba(227,179,65,0.08); color: #f0c040; }\n .dir-arrow { font-size: 8px; color: #484f58; width: 10px; flex-shrink: 0; line-height: 1; }\n .tree-connector { display: block; width: 1px; background: #21262d; margin-left: 13px; height: 100%; }\n .content-area {\n flex: 1; padding: 12px 14px; overflow-y: auto;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .content-area::-webkit-scrollbar { width: 4px; }\n .content-area::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .file-name { font-size: 11px; color: #484f58; margin-bottom: 8px; font-family: monospace; }\n pre {\n background: #0d1117; padding: 12px; border-radius: 8px;\n font-size: 11px; color: #c9d1d9; margin: 0;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n line-height: 1.7; border: 1px solid #21262d;\n white-space: pre; overflow-x: auto; overflow-y: auto;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n pre::-webkit-scrollbar { width: 4px; height: 4px; }\n pre::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .pre-block { font-size: 10.5px; }\n .pre-icp .sh-str { color: #85e89d; }\n .sh-kw { color: #ff7b72; }\n .sh-bi { color: #d2a8ff; }\n .sh-str { color: #a5d6ff; }\n .sh-cmt { color: #8b949e; font-style: italic; }\n .sh-num { color: #79c0ff; }\n .footer {\n padding: 10px 14px; border-top: 1px solid #21262d;\n display: flex; gap: 8px; justify-content: flex-end; background: #161b22;\n }\n button {\n padding: 6px 16px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s;\n }\n button:hover { background: #30363d; color: #e6edf3; }\n button:disabled { opacity: 0.35; cursor: default; }\n .btn-save { background: #2f81f7; border-color: #2f81f7; color: #fff; }\n .btn-save:hover { background: #1f6feb; border-color: #1f6feb; color: #fff; }\n .btn-save:disabled { background: #21262d; border-color: #30363d; color: #8b949e; }\n .placeholder { color: #484f58; font-size: 13px; padding: 28px; text-align: center; }\n .test-notes {\n margin: 0 0 10px; padding: 8px 12px;\n background: rgba(47,129,247,0.06); border-left: 3px solid rgba(47,129,247,0.4);\n border-radius: 0 6px 6px 0; font-size: 12px; color: #8b949e;\n line-height: 1.6; white-space: pre-wrap; word-break: break-word;\n }\n .block-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }\n .btn-copy {\n padding: 3px 10px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;\n font-size: 10px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap; flex-shrink: 0;\n }\n .btn-copy:hover { background: #30363d; color: #e6edf3; }\n .sidebar-toolbar {\n display: flex; gap: 4px; padding: 6px 6px 4px;\n border-bottom: 1px solid #21262d; flex-shrink: 0; background: #0d1117;\n }\n .btn-toolbar {\n flex: 1; padding: 4px 6px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;\n font-size: 10px; font-weight: 500; background: #161b22; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap; overflow: hidden;\n text-overflow: ellipsis;\n }\n .btn-toolbar:hover { background: #30363d; color: #e6edf3; }\n .btn-toolbar.btn-new { color: #3fb950; border-color: #238636; }\n .btn-toolbar.btn-new:hover { background: #238636; color: #fff; }\n .new-file-form {\n padding: 6px; border-bottom: 1px solid #21262d; display: flex; flex-direction: column; gap: 4px;\n }\n .new-file-form input {\n width: 100%; padding: 4px 7px; background: #0d1117; border: 1px solid #30363d;\n border-radius: 5px; color: #e6edf3; font-size: 11px; font-family: monospace;\n outline: none;\n }\n .new-file-form input:focus { border-color: #2f81f7; }\n .new-file-form .ext { font-size: 9px; color: #484f58; padding: 0 2px; }\n .new-file-actions { display: flex; gap: 4px; }\n .btn-confirm { flex: 1; padding: 3px 6px; border: 1px solid #238636; border-radius: 5px; cursor: pointer; font-size: 10px; font-weight: 500; background: #238636; color: #fff; transition: background 0.12s; }\n .btn-confirm:hover { background: #2ea043; }\n .btn-cancel-form { flex: 1; padding: 3px 6px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer; font-size: 10px; font-weight: 500; background: #21262d; color: #8b949e; transition: background 0.12s; }\n .btn-cancel-form:hover { background: #30363d; color: #e6edf3; }\n`;\n","import { escHtml, escAttr } from '../../utils/html.utils';\nimport { syntaxHighlight } from '../../utils/syntax-highlight.utils';\nimport type { DirectoryNode, FileNode } from '../../services/advanced-test.transformation.service';\n\nexport interface AdvancedEditorState {\n e2eTree: Array<DirectoryNode | FileNode>;\n selectedFile: unknown;\n selectedFileContent: string | null;\n testItBlock: string;\n interceptorsBlock: string;\n testNotes: string;\n saveButtonEnabled: boolean;\n isCreatingFile: boolean;\n collapsedDirs: Set<string>;\n sidebarWidth: number;\n}\n\nexport function renderNoPermission(needsReauth: boolean, t: (key: string) => string): string {\n const reauthBtn = needsReauth\n ? `<button id=\"btn-reauth\"\n style=\"margin-top:14px;padding:7px 16px;border:none;border-radius:6px;cursor:pointer;\n font-size:12px;font-weight:500;background:#2f81f7;color:#fff\">\n ${t('ADVANCED_EDITOR.REAUTH_BTN')}\n </button>`\n : '';\n\n return `\n <div class=\"no-perm\">\n <div>${needsReauth ? t('ADVANCED_EDITOR.PERMISSION_EXPIRED') : t('ADVANCED_EDITOR.NO_ACCESS')}</div>\n <div style=\"font-size:11px\">${needsReauth\n ? t('ADVANCED_EDITOR.PERMISSION_EXPIRED_HINT')\n : t('ADVANCED_EDITOR.NO_ACCESS_HINT')}</div>\n ${reauthBtn}\n </div>`;\n}\n\nexport function renderAdvancedEditor(state: AdvancedEditorState, t: (key: string) => string): string {\n const { e2eTree, selectedFile, selectedFileContent, testItBlock, interceptorsBlock, testNotes, saveButtonEnabled, isCreatingFile, collapsedDirs, sidebarWidth } = state;\n\n const treeHtml = e2eTree.length\n ? renderTree(e2eTree, selectedFile, collapsedDirs)\n : `<div class=\"tree-item\" style=\"color:#6c7a99\">${t('ADVANCED_EDITOR.NO_FILES')}</div>`;\n\n const contentHtml = selectedFileContent\n ? `<div class=\"file-name\">📄 ${escHtml((selectedFile as { name?: string } | null)?.name ?? '')}</div>\n <pre class=\"pre-file\">${syntaxHighlight(selectedFileContent.slice(0, 6000))}${selectedFileContent.length > 6000 ? '\\n...' : ''}</pre>`\n : `<div class=\"placeholder\">${t('ADVANCED_EDITOR.SELECT_FILE')}</div>`;\n\n const notesHtml = (testItBlock && testNotes)\n ? `<p class=\"test-notes\">${escHtml(testNotes)}</p>`\n : '';\n\n const itHtml = testItBlock\n ? `<div style=\"margin-top:10px\">\n <div class=\"file-name block-header\">\n <span>${t('ADVANCED_EDITOR.IT_LABEL')}</span>\n <button id=\"btn-copy-it\" class=\"btn-copy\">${t('ADVANCED_EDITOR.COPY_IT_BTN')}</button>\n </div>\n <pre class=\"pre-block\">${syntaxHighlight(testItBlock.slice(0, 3000))}</pre>\n </div>` : '';\n\n const interceptorsHtml = interceptorsBlock\n ? `<div style=\"margin-top:10px\">\n <div class=\"file-name block-header\">\n <span>${t('ADVANCED_EDITOR.BEFORE_EACH_LABEL')}</span>\n <button id=\"btn-copy-interceptors\" class=\"btn-copy\">${t('ADVANCED_EDITOR.COPY_ICP_BTN')}</button>\n </div>\n <pre class=\"pre-block pre-icp\">${syntaxHighlight(interceptorsBlock.slice(0, 3000))}</pre>\n </div>` : '';\n\n const newFileForm = isCreatingFile\n ? `<div class=\"new-file-form\">\n <input id=\"input-new-file\" type=\"text\" placeholder=\"${escHtml(t('ADVANCED_EDITOR.NEW_FILE_PLACEHOLDER'))}\" autocomplete=\"off\" />\n <span class=\"ext\">.cy.ts</span>\n <div class=\"new-file-actions\">\n <button id=\"btn-new-file-confirm\" class=\"btn-confirm\">${t('ADVANCED_EDITOR.NEW_FILE_CONFIRM')}</button>\n <button id=\"btn-new-file-cancel\" class=\"btn-cancel-form\">${t('ADVANCED_EDITOR.NEW_FILE_CANCEL')}</button>\n </div>\n </div>`\n : '';\n\n const toolbar = `\n <div class=\"sidebar-toolbar\">\n <button id=\"btn-new-file\" class=\"btn-toolbar btn-new\">${t('ADVANCED_EDITOR.NEW_FILE_BTN')}</button>\n <button id=\"btn-refresh\" class=\"btn-toolbar\">${t('ADVANCED_EDITOR.REFRESH_BTN')}</button>\n </div>`;\n\n return `\n <div class=\"layout\">\n <div class=\"sidebar\" style=\"width:${sidebarWidth}px\">\n ${toolbar}\n ${newFileForm}\n <div class=\"tree-scroll\">${treeHtml}</div>\n </div>\n <div id=\"resize-handle\" class=\"resize-handle\"></div>\n <div class=\"main\">\n <div class=\"content-area\">${contentHtml}${notesHtml}${itHtml}${interceptorsHtml}</div>\n <div class=\"footer\">\n <button id=\"btn-save\" class=\"btn-save\"\n ${!saveButtonEnabled || !testItBlock ? 'disabled' : ''}>\n ${t('ADVANCED_EDITOR.INSERT_BTN')}\n </button>\n <button id=\"btn-edit\" ${!saveButtonEnabled ? 'disabled' : ''}>\n ${t('ADVANCED_EDITOR.EDIT_MANUAL_BTN')}\n </button>\n <button id=\"btn-close\">${t('ADVANCED_EDITOR.CLOSE_BTN')}</button>\n </div>\n </div>\n </div>`;\n}\n\nexport function renderTree(\n nodes: Array<DirectoryNode | FileNode>,\n selected: unknown,\n collapsedDirs: Set<string>,\n indent = 0,\n parentPath = '',\n): string {\n return nodes.map((n) => {\n const currentPath = parentPath ? `${parentPath}/${n.name}` : n.name;\n const isFile = n.kind === 'file';\n const pad = `padding-left:${6 + indent * 14}px`;\n\n if (!isFile) {\n const dir = n as DirectoryNode;\n const hasChildren = (dir.children?.length ?? 0) > 0;\n const isCollapsed = collapsedDirs.has(currentPath);\n const arrow = hasChildren ? (isCollapsed ? '▶' : '▼') : '·';\n const dirHtml = `<div class=\"tree-item dir\" style=\"${pad}\" data-dir-path=\"${escAttr(currentPath)}\">\n <span class=\"dir-arrow\">${arrow}</span>📁 ${escHtml(n.name)}\n </div>`;\n if (!hasChildren || isCollapsed) return dirHtml;\n return dirHtml + renderTree(dir.children, selected, collapsedDirs, indent + 1, currentPath);\n }\n\n const isSel = (selected as { name?: string } | null)?.name === n.name;\n const cls = `tree-item${isSel ? ' selected' : ''}`;\n const data = JSON.stringify({ kind: n.kind, name: n.name }).replace(/\"/g, '&quot;');\n return `<div class=\"${cls}\" style=\"${pad}\" data-file=\"${data}\">📄 ${escHtml(n.name)}</div>`;\n }).join('');\n}\n\nexport async function findFileHandleRecursive(\n dir: FileSystemDirectoryHandle,\n name: string,\n): Promise<FileSystemFileHandle | null> {\n for await (const entry of dir.values()) {\n if (entry.kind === 'file' && entry.name === name) return entry as FileSystemFileHandle;\n if (entry.kind === 'directory') {\n const found = await findFileHandleRecursive(entry as FileSystemDirectoryHandle, name);\n if (found) return found;\n }\n }\n return null;\n}\n","import { PersistenceService } from '../../services/persistence.service';\r\nimport { TranslationService } from '../../services/translation.service';\r\nimport { AdvancedTestTransformationService } from '../../services/advanced-test.transformation.service';\r\nimport { ADVANCED_TEST_EDITOR_STYLES } from './advanced-test-editor.styles';\r\nimport { renderNoPermission, renderAdvancedEditor, findFileHandleRecursive } from './advanced-test-editor.template';\r\nimport type { DirectoryNode, FileNode } from '../../services/advanced-test.transformation.service';\r\n\r\nexport class AdvancedTestEditorElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private readonly transformationService = new AdvancedTestTransformationService();\r\n\r\n persistence!: PersistenceService;\r\n translation!: TranslationService;\r\n testId?: number;\r\n\r\n e2eTree: Array<DirectoryNode | FileNode> = [];\r\n selectedFile: unknown = null;\r\n saveButtonEnabled = false;\r\n selectedFileHandle: FileSystemFileHandle | null = null;\r\n selectedFileContent: string | null = null;\r\n testItBlock = '';\r\n interceptorsBlock = '';\r\n testNotes = '';\r\n isPreviewMode = false;\r\n previewFileName: string | null = null;\r\n previewFileContent: string | null = null;\r\n isCreatingFile = false;\r\n collapsedDirs: Set<string> = new Set();\r\n sidebarWidth = 220;\r\n private hasPermission = false;\r\n private needsReauth = false;\r\n private _dirHandle: FileSystemDirectoryHandle | null = null;\r\n private _e2eHandle: FileSystemDirectoryHandle | null = null;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.persistence) this.persistence = new PersistenceService();\r\n if (!this.translation) this.translation = new TranslationService();\r\n this.init();\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n private async init(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig();\r\n const allowed = config?.['allowReadWriteFiles'] === 'true';\r\n\r\n if (!allowed) {\r\n this.hasPermission = false;\r\n if (this.testId !== undefined) await this.loadCypressCommandsForTest(this.testId);\r\n this.render();\r\n return;\r\n }\r\n\r\n const handle = config?.['cypressDirectoryHandle'] as FileSystemDirectoryHandle | null;\r\n if (!handle) {\r\n this.hasPermission = false;\r\n if (this.testId !== undefined) await this.loadCypressCommandsForTest(this.testId);\r\n this.render();\r\n return;\r\n }\r\n\r\n // queryPermission does NOT require a user gesture\r\n const perm = await (handle as unknown as FileSystemHandleWithPermission).queryPermission({ mode: 'readwrite' });\r\n this._dirHandle = handle;\r\n this.hasPermission = perm === 'granted';\r\n this.needsReauth = perm === 'prompt';\r\n\r\n if (this.testId !== undefined) await this.loadCypressCommandsForTest(this.testId);\r\n if (this.hasPermission) await this.getFoldersData();\r\n this.render();\r\n }\r\n\r\n async getFoldersData(): Promise<void> {\r\n if (!this.hasPermission || !this._dirHandle) return;\r\n try {\r\n for await (const entry of this._dirHandle.values()) {\r\n if (entry.kind === 'directory' && entry.name === 'e2e') {\r\n this._e2eHandle = entry as FileSystemDirectoryHandle;\r\n const tree = await this.transformationService.scanDirectory(this._e2eHandle);\r\n this.e2eTree = tree.children ?? [];\r\n this.render();\r\n return;\r\n }\r\n }\r\n } catch { /* silently skip permission errors */ }\r\n }\r\n\r\n async createNewFile(rawName: string): Promise<void> {\r\n if (!this._e2eHandle) return;\r\n const name = rawName.trim().replace(/\\.cy\\.ts$/, '');\r\n if (!name) return;\r\n const fileName = `${name}.cy.ts`;\r\n const template = `describe('${name}', () => {\\n\\n it('should ', () => {\\n\\n });\\n\\n});\\n`;\r\n try {\r\n const fileHandle = await this._e2eHandle.getFileHandle(fileName, { create: true });\r\n const writable = await fileHandle.createWritable();\r\n await writable.write(template);\r\n await writable.close();\r\n } catch { /* silently ignore if file already exists or permission denied */ }\r\n this.isCreatingFile = false;\r\n await this.getFoldersData();\r\n }\r\n\r\n async refreshTree(): Promise<void> {\r\n await this.getFoldersData();\r\n }\r\n\r\n async saveCommandsToFile(): Promise<void> {\r\n if (!this.selectedFileHandle || !this.selectedFileContent || !this.testItBlock) return;\r\n let content = this.selectedFileContent;\r\n if (this.interceptorsBlock) {\r\n content = this.transformationService.insertBeforeEach(content, this.interceptorsBlock);\r\n }\r\n const comment = this.testNotes ? this.transformationService.buildBlockComment(this.testNotes) + '\\n' : '';\r\n content = this.transformationService.insertItBlock(content, comment + this.testItBlock);\r\n if (!content) return;\r\n const writable = await this.selectedFileHandle.createWritable();\r\n await writable.write(content);\r\n await writable.close();\r\n this.dispatchEvent(new CustomEvent('closemodal', { bubbles: true, composed: true }));\r\n }\r\n\r\n async onFileClick(file: unknown): Promise<void> {\r\n if (!this.transformationService.isFile(file)) return;\r\n this.selectedFile = file;\r\n this.saveButtonEnabled = true;\r\n\r\n if (!this._dirHandle) return;\r\n const handle = await findFileHandleRecursive(this._dirHandle, (file as { name: string }).name);\r\n if (!handle) return;\r\n this.selectedFileHandle = handle;\r\n const fileObj = await handle.getFile();\r\n this.selectedFileContent = await fileObj.text();\r\n this.render();\r\n }\r\n\r\n markFileAsSelected(file: unknown): void {\r\n this.selectedFile = file;\r\n }\r\n\r\n async loadCypressCommandsForTest(testId: number): Promise<void> {\r\n const test = await this.persistence.getTestById(testId);\r\n if (test) {\r\n this.testItBlock = test.itBlock ?? '';\r\n this.interceptorsBlock = test.interceptorsBlock ?? '';\r\n this.testNotes = test.notes ?? '';\r\n } else {\r\n this.testItBlock = '';\r\n this.interceptorsBlock = '';\r\n this.testNotes = '';\r\n }\r\n this.render();\r\n }\r\n\r\n copyToClipboard(text: string): void {\r\n navigator.clipboard?.writeText(text);\r\n }\r\n\r\n openEditManually(): void {\r\n if (!this.selectedFileHandle || !this.selectedFileContent) return;\r\n this.dispatchEvent(new CustomEvent('openfileeditor', {\r\n detail: {\r\n handle: this.selectedFileHandle,\r\n content: this.selectedFileContent,\r\n fileName: (this.selectedFile as { name?: string } | null)?.name ?? '',\r\n testId: this.testId,\r\n itBlock: this.testItBlock,\r\n interceptorsBlock: this.interceptorsBlock,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n }));\r\n }\r\n\r\n toggleDir(path: string): void {\r\n if (this.collapsedDirs.has(path)) {\r\n this.collapsedDirs.delete(path);\r\n } else {\r\n this.collapsedDirs.add(path);\r\n }\r\n this.render();\r\n }\r\n\r\n private setupResizeHandle(): void {\r\n const handle = this.shadow.getElementById('resize-handle');\r\n const sidebar = this.shadow.querySelector('.sidebar') as HTMLElement | null;\r\n if (!handle || !sidebar) return;\r\n\r\n let startX = 0;\r\n let startWidth = 0;\r\n\r\n const onMouseMove = (e: MouseEvent) => {\r\n const delta = e.clientX - startX;\r\n const newWidth = Math.max(140, Math.min(500, startWidth + delta));\r\n this.sidebarWidth = newWidth;\r\n sidebar.style.width = `${newWidth}px`;\r\n };\r\n\r\n const onMouseUp = () => {\r\n document.removeEventListener('mousemove', onMouseMove);\r\n document.removeEventListener('mouseup', onMouseUp);\r\n document.body.style.cursor = '';\r\n document.body.style.userSelect = '';\r\n handle.classList.remove('dragging');\r\n };\r\n\r\n handle.addEventListener('mousedown', (e: MouseEvent) => {\r\n startX = e.clientX;\r\n startWidth = sidebar.offsetWidth;\r\n document.addEventListener('mousemove', onMouseMove);\r\n document.addEventListener('mouseup', onMouseUp);\r\n document.body.style.cursor = 'col-resize';\r\n document.body.style.userSelect = 'none';\r\n handle.classList.add('dragging');\r\n e.preventDefault();\r\n });\r\n }\r\n\r\n closePreview(): void {\r\n this.isPreviewMode = false;\r\n this.previewFileName = null;\r\n this.previewFileContent = null;\r\n if (this.testId !== undefined) {\r\n this.dispatchEvent(new CustomEvent('closemodal', { bubbles: true, composed: true }));\r\n }\r\n this.render();\r\n }\r\n\r\n private render(): void {\r\n if (!this.hasPermission) {\r\n this.shadow.innerHTML = `<style>${ADVANCED_TEST_EDITOR_STYLES}</style>${renderNoPermission(this.needsReauth, this.t.bind(this))}`;\r\n\r\n this.shadow.getElementById('btn-reauth')?.addEventListener('click', async () => {\r\n if (!this._dirHandle) return;\r\n const perm = await (this._dirHandle as unknown as FileSystemHandleWithPermission).requestPermission({ mode: 'readwrite' });\r\n if (perm === 'granted') {\r\n this.hasPermission = true;\r\n this.needsReauth = false;\r\n await this.getFoldersData();\r\n this.render();\r\n }\r\n });\r\n return;\r\n }\r\n\r\n this.shadow.innerHTML = `<style>${ADVANCED_TEST_EDITOR_STYLES}</style>${renderAdvancedEditor({\r\n e2eTree: this.e2eTree,\r\n selectedFile: this.selectedFile,\r\n selectedFileContent: this.selectedFileContent,\r\n testItBlock: this.testItBlock,\r\n interceptorsBlock: this.interceptorsBlock,\r\n testNotes: this.testNotes,\r\n saveButtonEnabled: this.saveButtonEnabled,\r\n isCreatingFile: this.isCreatingFile,\r\n collapsedDirs: this.collapsedDirs,\r\n sidebarWidth: this.sidebarWidth,\r\n }, this.t.bind(this))}`;\r\n\r\n this.shadow.querySelectorAll('[data-file]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n const data = (el as HTMLElement).dataset['file'];\r\n if (data) this.onFileClick(JSON.parse(data));\r\n });\r\n });\r\n this.shadow.querySelectorAll('[data-dir-path]').forEach((el) => {\r\n el.addEventListener('click', () => {\r\n const path = (el as HTMLElement).dataset['dirPath'];\r\n if (path) this.toggleDir(path);\r\n });\r\n });\r\n this.setupResizeHandle();\r\n this.shadow.getElementById('btn-save')\r\n ?.addEventListener('click', () => this.saveCommandsToFile());\r\n this.shadow.getElementById('btn-edit')\r\n ?.addEventListener('click', () => this.openEditManually());\r\n this.shadow.getElementById('btn-copy-it')\r\n ?.addEventListener('click', () => this.copyToClipboard(this.testItBlock));\r\n this.shadow.getElementById('btn-copy-interceptors')\r\n ?.addEventListener('click', () => this.copyToClipboard(this.interceptorsBlock));\r\n this.shadow.getElementById('btn-close')\r\n ?.addEventListener('click', () => this.closePreview());\r\n this.shadow.getElementById('btn-new-file')\r\n ?.addEventListener('click', () => {\r\n this.isCreatingFile = !this.isCreatingFile;\r\n this.render();\r\n if (this.isCreatingFile) this.shadow.getElementById('input-new-file')?.focus();\r\n });\r\n this.shadow.getElementById('btn-refresh')\r\n ?.addEventListener('click', () => this.refreshTree());\r\n this.shadow.getElementById('btn-new-file-confirm')\r\n ?.addEventListener('click', () => {\r\n const input = this.shadow.getElementById('input-new-file') as HTMLInputElement | null;\r\n this.createNewFile(input?.value ?? '');\r\n });\r\n this.shadow.getElementById('btn-new-file-cancel')\r\n ?.addEventListener('click', () => {\r\n this.isCreatingFile = false;\r\n this.render();\r\n });\r\n const input = this.shadow.getElementById('input-new-file') as HTMLInputElement | null;\r\n input?.addEventListener('keydown', (e) => {\r\n if (e.key === 'Enter') {\r\n this.createNewFile(input.value);\r\n } else if (e.key === 'Escape') {\r\n this.isCreatingFile = false;\r\n this.render();\r\n }\r\n });\r\n }\r\n}\r\n\r\nif (!customElements.get('advanced-test-editor')) {\r\n customElements.define('advanced-test-editor', AdvancedTestEditorElement);\r\n}\r\n","export const FILE_PREVIEW_STYLES = `\n :host { display: block; height: 100%; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }\n * { box-sizing: border-box; }\n .container { display: flex; flex-direction: column; height: 100%; }\n .header {\n display: flex; align-items: center; gap: 8px;\n padding: 8px 12px; border-bottom: 1px solid #21262d;\n background: #161b22;\n }\n .file-name { flex: 1; font-size: 12px; color: #8b949e;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; }\n .body { display: flex; flex: 1; overflow: hidden; min-height: 0; }\n .editor {\n flex: 1; min-width: 0; padding: 14px;\n background: #0d1117; color: #c9d1d9; border: none; outline: none;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 12px;\n line-height: 1.7; resize: none;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .editor::-webkit-scrollbar { width: 5px; }\n .editor::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }\n .blocks-panel {\n width: 260px; flex-shrink: 0; border-left: 1px solid #21262d;\n background: #0d1117; padding: 10px 12px; overflow-y: auto;\n display: flex; flex-direction: column; gap: 10px;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .blocks-panel::-webkit-scrollbar { width: 4px; }\n .blocks-panel::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }\n .block-section { display: flex; flex-direction: column; gap: 4px; }\n .block-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 2px; }\n .block-label { font-size: 10px; color: #484f58; text-transform: uppercase; letter-spacing: 0.6px; font-weight: 600; }\n .btn-copy-sm {\n padding: 2px 8px; border: 1px solid #30363d; border-radius: 4px; cursor: pointer;\n font-size: 10px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.12s, color 0.12s; white-space: nowrap;\n }\n .btn-copy-sm:hover { background: #30363d; color: #e6edf3; }\n .block-pre {\n margin: 0; padding: 6px 8px; background: #161b22;\n border-radius: 5px; border: 1px solid #21262d;\n font-size: 10px; color: #c9d1d9; line-height: 1.6;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;\n max-height: 280px; overflow-y: auto; white-space: pre-wrap; word-break: break-all;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .diff-panel {\n flex: 1; overflow-y: auto; background: #0d1117; border-left: 1px solid #21262d;\n padding: 8px 0; min-width: 0;\n font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace; font-size: 11px;\n line-height: 1.6;\n scrollbar-width: thin; scrollbar-color: #30363d transparent;\n }\n .diff-panel::-webkit-scrollbar { width: 5px; }\n .diff-panel::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }\n .diff-line {\n display: flex; gap: 0; white-space: pre; padding: 0 12px;\n }\n .diff-line.added { background: rgba(63,185,80,0.12); color: #3fb950; }\n .diff-line.removed { background: rgba(248,81,73,0.1); color: #f85149; }\n .diff-line.same { color: #484f58; }\n .diff-sign { width: 14px; flex-shrink: 0; user-select: none; }\n .diff-empty { color: #484f58; font-size: 12px; padding: 20px; text-align: center; }\n .footer {\n display: flex; gap: 8px; padding: 8px 12px;\n border-top: 1px solid #21262d; justify-content: flex-end;\n background: #161b22;\n }\n button {\n padding: 6px 14px; border: 1px solid #30363d; border-radius: 6px; cursor: pointer;\n font-size: 12px; font-weight: 500; background: #21262d; color: #8b949e;\n transition: background 0.15s, color 0.12s;\n }\n button:hover { background: #30363d; color: #e6edf3; }\n .btn-save { background: #3fb950; border-color: #3fb950; color: #fff; }\n .btn-save:hover { background: #2ea043; border-color: #2ea043; }\n .btn-launch { background: transparent; border-color: #e3b341; color: #e3b341; }\n .btn-launch:hover { background: rgba(227,179,65,0.1); }\n .btn-diff-active { background: rgba(47,129,247,0.15); border-color: rgba(47,129,247,0.4); color: #2f81f7; }\n`;\n","import { escHtml } from '../../utils/html.utils';\n\nexport type DiffEntry = { type: 'same' | 'added' | 'removed'; line: string };\n\nexport function computeDiff(original: string, modified: string): DiffEntry[] {\n const MAX_LINES = 600;\n const a = original.split('\\n').slice(0, MAX_LINES);\n const b = modified.split('\\n').slice(0, MAX_LINES);\n const m = a.length, n = b.length;\n\n const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]);\n }\n }\n\n const result: DiffEntry[] = [];\n let i = m, j = n;\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n result.unshift({ type: 'same', line: a[i - 1] });\n i--; j--;\n } else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {\n result.unshift({ type: 'added', line: b[j - 1] });\n j--;\n } else {\n result.unshift({ type: 'removed', line: a[i - 1] });\n i--;\n }\n }\n return result;\n}\n\nexport function buildDiffHtml(original: string, current: string, t: (key: string) => string): string {\n if (original === current) return `<div class=\"diff-empty\">${t('FILE_PREVIEW.NO_CHANGES')}</div>`;\n\n const diff = computeDiff(original, current);\n if (!diff.length) return `<div class=\"diff-empty\">${t('FILE_PREVIEW.NO_CHANGES_SHORT')}</div>`;\n\n const CONTEXT = 2;\n const compressed: DiffEntry[] = [];\n let sameRun = 0;\n for (let idx = 0; idx < diff.length; idx++) {\n if (diff[idx].type === 'same') {\n sameRun++;\n if (sameRun <= CONTEXT) compressed.push(diff[idx]);\n else if (idx + 1 < diff.length && diff[idx + 1].type !== 'same') {\n if (sameRun > CONTEXT * 2) compressed.push({ type: 'same', line: '…' });\n compressed.push(diff[idx]);\n }\n } else {\n sameRun = 0;\n compressed.push(diff[idx]);\n }\n }\n\n return compressed.map(({ type, line }) => {\n const sign = type === 'added' ? '+' : type === 'removed' ? '−' : ' ';\n return `<div class=\"diff-line ${type}\"><span class=\"diff-sign\">${sign}</span><span>${escHtml(line)}</span></div>`;\n }).join('');\n}\n\nexport interface FilePreviewState {\n fileName: string | null;\n showDiff: boolean;\n fileContent: string | null;\n originalContent: string | null;\n currentContent: string;\n itBlock: string;\n interceptorsBlock: string;\n closeLabel: string;\n}\n\nexport function renderFilePreview(state: FilePreviewState, t: (key: string) => string): string {\n const { fileName, showDiff, fileContent, originalContent, currentContent, itBlock, interceptorsBlock, closeLabel } = state;\n\n const blocksPanelHtml = (itBlock || interceptorsBlock) ? `\n <div class=\"blocks-panel\">\n ${itBlock ? `\n <div class=\"block-section\">\n <div class=\"block-row\">\n <span class=\"block-label\">${t('FILE_PREVIEW.BLOCK_IT')}</span>\n <button id=\"btn-copy-it\" class=\"btn-copy-sm\">${t('FILE_PREVIEW.COPY_BTN')}</button>\n </div>\n <pre class=\"block-pre\">${escHtml(itBlock.slice(0, 2000))}</pre>\n </div>` : ''}\n ${interceptorsBlock ? `\n <div class=\"block-section\">\n <div class=\"block-row\">\n <span class=\"block-label\">${t('FILE_PREVIEW.BLOCK_BEFORE_EACH')}</span>\n <button id=\"btn-copy-icp\" class=\"btn-copy-sm\">${t('FILE_PREVIEW.COPY_BTN')}</button>\n </div>\n <pre class=\"block-pre\" style=\"color:#3fb950\">${escHtml(interceptorsBlock.slice(0, 2000))}</pre>\n </div>` : ''}\n </div>` : '';\n\n const hasChanges = originalContent !== null && originalContent !== (fileContent ?? '');\n\n return `\n <div class=\"container\">\n <div class=\"header\">\n <span class=\"file-name\">📄 ${fileName ? escHtml(fileName) : t('FILE_PREVIEW.NO_FILE')}</span>\n <button id=\"btn-copy\" title=\"${t('FILE_PREVIEW.COPY_TITLE')}\">📋</button>\n </div>\n <div class=\"body\">\n ${showDiff\n ? `<div class=\"diff-panel\" id=\"diff-panel\">${buildDiffHtml(originalContent ?? '', currentContent, t)}</div>`\n : `<textarea class=\"editor\" id=\"editor\" spellcheck=\"false\">${escHtml(fileContent ?? '')}</textarea>`}\n ${blocksPanelHtml}\n </div>\n <div class=\"footer\">\n <button id=\"btn-launch\" class=\"btn-launch\">${t('FILE_PREVIEW.LAUNCH_BTN')}</button>\n ${hasChanges ? `<button id=\"btn-diff\" class=\"${showDiff ? 'btn-diff-active' : ''}\">${t('FILE_PREVIEW.DIFF_BTN')}</button>` : ''}\n <button id=\"btn-save\" class=\"btn-save\">${t('FILE_PREVIEW.SAVE_BTN')}</button>\n <button id=\"btn-close\">${escHtml(closeLabel || t('FILE_PREVIEW.CLOSE_BTN'))}</button>\n </div>\n </div>`;\n}\n","import { translationService, type TranslationService } from '../../services/translation.service';\r\nimport { FILE_PREVIEW_STYLES } from './file-preview.styles';\r\nimport { renderFilePreview } from './file-preview.template';\r\n\r\nexport class FilePreviewElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private textarea: HTMLTextAreaElement | null = null;\r\n\r\n fileName: string | null = null;\r\n closeLabel = '';\r\n translation: TranslationService = translationService;\r\n itBlock = '';\r\n interceptorsBlock = '';\r\n commands: string[] = [];\r\n interceptors: string[] = [];\r\n private _fileContent: string | null = null;\r\n private _originalContent: string | null = null;\r\n private _showDiff = false;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if (!this.closeLabel) this.closeLabel = this.translation.translate('FILE_PREVIEW.CLOSE_BTN');\r\n this.render();\r\n }\r\n\r\n private t(key: string): string { return this.translation.translate(key); }\r\n\r\n get fileContent(): string | null { return this._fileContent; }\r\n set fileContent(v: string | null) {\r\n if (this._originalContent === null) this._originalContent = v;\r\n this._fileContent = v;\r\n if (this.textarea) this.textarea.value = v ?? '';\r\n else this.render();\r\n }\r\n\r\n saveFile(): void {\r\n const content = this.textarea?.value ?? this._fileContent ?? '';\r\n this.dispatchEvent(new CustomEvent('save', { detail: content, bubbles: true, composed: true }));\r\n }\r\n\r\n onClose(): void {\r\n this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }));\r\n }\r\n\r\n async launchTest(specPath?: string): Promise<void> {\r\n const path = specPath ?? (this.fileName ? `cypress/e2e/${this.fileName}` : '');\r\n if (!path) return;\r\n const response = await fetch('http://localhost:8123/run-test', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ specPath: path }),\r\n });\r\n await response.json();\r\n }\r\n\r\n copyToClipboard(text: string): void {\r\n navigator.clipboard?.writeText(text);\r\n }\r\n\r\n toggleDiff(): void {\r\n this._showDiff = !this._showDiff;\r\n this.render();\r\n }\r\n\r\n private render(): void {\r\n this.shadow.innerHTML = `<style>${FILE_PREVIEW_STYLES}</style>${renderFilePreview({\r\n fileName: this.fileName,\r\n showDiff: this._showDiff,\r\n fileContent: this._fileContent,\r\n originalContent: this._originalContent,\r\n currentContent: this.textarea?.value ?? this._fileContent ?? '',\r\n itBlock: this.itBlock,\r\n interceptorsBlock: this.interceptorsBlock,\r\n closeLabel: this.closeLabel,\r\n }, this.t.bind(this))}`;\r\n\r\n this.textarea = this.shadow.getElementById('editor') as HTMLTextAreaElement | null;\r\n if (this.textarea) {\r\n const ta = this.textarea;\r\n this.textarea.addEventListener('input', () => {\r\n this._fileContent = ta.value;\r\n });\r\n }\r\n this.shadow.getElementById('btn-save')?.addEventListener('click', () => this.saveFile());\r\n this.shadow.getElementById('btn-close')?.addEventListener('click', () => this.onClose());\r\n this.shadow.getElementById('btn-launch')?.addEventListener('click', () => this.launchTest());\r\n this.shadow.getElementById('btn-copy')?.addEventListener('click', () => {\r\n this.copyToClipboard(this.textarea?.value ?? this._fileContent ?? '');\r\n });\r\n this.shadow.getElementById('btn-diff')?.addEventListener('click', () => this.toggleDiff());\r\n this.shadow.getElementById('btn-copy-it')?.addEventListener('click', () => {\r\n this.copyToClipboard(this.itBlock);\r\n });\r\n this.shadow.getElementById('btn-copy-icp')?.addEventListener('click', () => {\r\n this.copyToClipboard(this.interceptorsBlock);\r\n });\r\n }\r\n}\r\n\r\nif (!customElements.get('file-preview')) {\r\n customElements.define('file-preview', FilePreviewElement);\r\n}\r\n","import Swal from 'sweetalert2';\r\nimport { getRecorderStyles } from './lib-e2e-recorder.styles';\r\nimport { renderRecorderWidget } from './lib-e2e-recorder.template';\r\nimport { RecordingService, type SelectorStrategy } from '../../services/recording.service';\r\nimport { PersistenceService } from '../../services/persistence.service';\r\nimport { TranslationService } from '../../services/translation.service';\r\nimport { HttpMonitor } from '../../services/http-monitor';\r\nimport {\r\n injectStyles,\r\n LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES,\r\n SCROLLBAR_STYLES,\r\n} from '../../utils/styles.utils';\r\nimport {\r\n makeModalResizable,\r\n makeSwalDraggable,\r\n setSwal2DataCyAttribute,\r\n} from '../../utils/modal.utils';\r\nimport type { Lang } from '../../models/lang.model';\r\nimport { showToast } from '../../utils/toast.utils';\r\n\r\n/**\r\n * Minimal property/event shapes for dynamically-created child custom elements.\r\n * Not extending HTMLElement avoids conflicts with the strict EventListener signature;\r\n * cast to Node/HTMLElement only for actual DOM insertion.\r\n */\r\ninterface PrevisualizerEl {\r\n translation: TranslationService; commands: string[]; interceptors: string[]; editable: boolean;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void): void;\r\n}\r\ninterface TestEditorEl { persistence: PersistenceService; translation: TranslationService }\r\ninterface SaveTestEl {\r\n translation: TranslationService;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void): void;\r\n}\r\ninterface ConfigEl {\r\n persistence: PersistenceService; translation: TranslationService;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void): void;\r\n}\r\ninterface AdvancedEditorEl {\r\n persistence: PersistenceService; translation: TranslationService; testId?: number;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void | Promise<void>): void;\r\n}\r\ninterface FilePreviewEl {\r\n translation: TranslationService; fileContent: string | null; fileName: string | null;\r\n closeLabel: string; itBlock: string; interceptorsBlock: string;\r\n addEventListener(type: string, listener: (e: CustomEvent) => void | Promise<void>): void;\r\n}\r\ninterface SelectorPickerEl {\r\n targetElement: HTMLElement; recording: RecordingService; translation: TranslationService;\r\n}\r\n\r\nexport class LibE2eRecorderElement extends HTMLElement {\r\n private shadow: ShadowRoot;\r\n private _isDisabled = false;\r\n private keydownHandler!: (e: KeyboardEvent) => void;\r\n private recordingUnsub?: () => void;\r\n private commandsUnsub?: () => void;\r\n private interceptorsUnsub?: () => void;\r\n private pauseUnsub?: () => void;\r\n private selectorNotFoundUnsub?: () => void;\r\n private controlFirstTimeData = true;\r\n private _previsualizerRef: { commands: string[]; interceptors: string[] } | null = null;\r\n private httpMonitor?: HttpMonitor;\r\n private smartSelectorEnabled = true;\r\n\r\n recording!: RecordingService;\r\n persistence!: PersistenceService;\r\n translation!: TranslationService;\r\n\r\n isVisible = false;\r\n isRecording = false;\r\n isPaused = false;\r\n cypressCommands: string[] = [];\r\n interceptors: string[] = [];\r\n\r\n isCommandsDialogOpen = false;\r\n isSavedTestsDialogOpen = false;\r\n isSaveTestDialogOpen = false;\r\n isSettingsDialogOpen = false;\r\n isAdvancedEditorDialogOpen = false;\r\n\r\n constructor() {\r\n super();\r\n this.shadow = this.attachShadow({ mode: 'open' });\r\n }\r\n\r\n connectedCallback(): void {\r\n if ('Cypress' in window) {\r\n this._isDisabled = true;\r\n return;\r\n }\r\n if (!this.getAttribute('data-cy')) {\r\n this.setAttribute('data-cy', 'lib-e2e-cypress-for-dummys');\r\n }\r\n if (!this.recording) this.recording = new RecordingService();\r\n if (!this.persistence) this.persistence = new PersistenceService();\r\n if (!this.translation) this.translation = new TranslationService();\r\n\r\n this.httpMonitor = new HttpMonitor(this.recording);\r\n this.httpMonitor.install();\r\n\r\n injectStyles(LIB_E2E_CYPRESS_FOR_DUMMYS_SWAL2_STYLES, 'lib-e2e-swal2-styles');\r\n injectStyles(SCROLLBAR_STYLES, 'lib-e2e-scrollbar-styles');\r\n\r\n this.initHttpConfig();\r\n this.initLanguage();\r\n this.initFilesystemAccess();\r\n this.initSelectorStrategy();\r\n this.initSubscriptions();\r\n this.render();\r\n this.initVisibility();\r\n\r\n this.keydownHandler = (e: KeyboardEvent) => this.handleKeyboardEvent(e);\r\n window.addEventListener('keydown', this.keydownHandler);\r\n }\r\n\r\n disconnectedCallback(): void {\r\n if (this._isDisabled) return;\r\n window.removeEventListener('keydown', this.keydownHandler);\r\n this.recordingUnsub?.();\r\n this.commandsUnsub?.();\r\n this.interceptorsUnsub?.();\r\n this.pauseUnsub?.();\r\n this.selectorNotFoundUnsub?.();\r\n this.httpMonitor?.uninstall();\r\n this.recording.destroy();\r\n }\r\n\r\n private async initHttpConfig(): Promise<void> {\r\n const config = await this.persistence.getConfig('extendedHttpCommands');\r\n if (config === null) {\r\n await this.persistence.setConfig({ extendedHttpCommands: 'true' });\r\n localStorage.setItem('extendedHttpCommands', 'true');\r\n } else {\r\n localStorage.setItem('extendedHttpCommands', (config['extendedHttpCommands'] as string) ?? 'true');\r\n }\r\n }\r\n\r\n private async initLanguage(): Promise<void> {\r\n const config = await this.persistence.getConfig('language');\r\n const lang = config?.['language'] as Lang | undefined;\r\n this.translation.setLang(lang ?? this.translation.detectLang());\r\n }\r\n\r\n private initSubscriptions(): void {\r\n this.recordingUnsub = this.recording.onRecordingChange((val) => {\r\n this.isRecording = val;\r\n if (!val && !this.controlFirstTimeData) {\r\n this.saveRecordingHistory();\r\n this.showSaveTestDialog();\r\n }\r\n this.controlFirstTimeData = false;\r\n this.render();\r\n });\r\n this.commandsUnsub = this.recording.onCommandsChange((cmds) => {\r\n this.cypressCommands = cmds;\r\n if (this._previsualizerRef) this._previsualizerRef.commands = cmds;\r\n });\r\n this.interceptorsUnsub = this.recording.onInterceptorsChange((icps) => {\r\n this.interceptors = icps;\r\n if (this._previsualizerRef) this._previsualizerRef.interceptors = icps;\r\n });\r\n this.pauseUnsub = this.recording.onPauseChange((paused) => {\r\n this.isPaused = paused;\r\n this.render();\r\n });\r\n this.selectorNotFoundUnsub = this.recording.onSelectorNotFound((target) => {\r\n if (this.smartSelectorEnabled) this.showSelectorPicker(target);\r\n });\r\n }\r\n\r\n private showSelectorPicker(target: HTMLElement): void {\r\n import('../../components/selector-picker/selector-picker').then(() => {\r\n const existing = document.querySelector('selector-picker');\r\n if (existing) existing.remove();\r\n\r\n const picker = document.createElement('selector-picker') as unknown as SelectorPickerEl;\r\n picker.targetElement = target;\r\n picker.recording = this.recording;\r\n picker.translation = this.translation;\r\n document.body.appendChild(picker as unknown as Node);\r\n });\r\n }\r\n\r\n private async initVisibility(): Promise<void> {\r\n if (this.hasAttribute('start-hidden')) {\r\n // Attribute overrides DB: presence → hidden, explicit \"false\" → visible\r\n this.isVisible = this.getAttribute('start-hidden') === 'false';\r\n this.style.display = this.isVisible ? '' : 'none';\r\n return;\r\n }\r\n const config = await this.persistence.getGeneralConfig();\r\n this.isVisible = config?.['startHidden'] !== 'true';\r\n this.style.display = this.isVisible ? '' : 'none';\r\n }\r\n\r\n private async initSelectorStrategy(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig();\r\n const strategy = config?.['selectorStrategy'] as string | undefined;\r\n if (strategy) this.recording.selectorStrategy = strategy as SelectorStrategy;\r\n this.smartSelectorEnabled = config?.['smartSelectorEnabled'] !== 'false';\r\n }\r\n\r\n toggle(): void {\r\n this.recording.toggleRecording();\r\n }\r\n\r\n togglePause(): void {\r\n this.recording.togglePause();\r\n }\r\n\r\n setLanguage(lang?: string): void {\r\n const resolved = lang ? (lang as Lang) : this.translation.detectLang();\r\n this.translation.setLang(resolved);\r\n }\r\n\r\n handleKeyboardEvent(event: KeyboardEvent): void {\r\n if (!event.ctrlKey) return;\r\n const key = event.key.toLowerCase();\r\n if (key === 'e' && event.shiftKey) { event.preventDefault(); this.toggleVisibility(); return; }\r\n if (!this.isVisible) return;\r\n if (key === 'r') { event.preventDefault(); this.toggle(); }\r\n else if (key === 'p') { event.preventDefault(); this.togglePause(); }\r\n else if (key === '1') { event.preventDefault(); this.showSavedTestsDialog(); }\r\n else if (key === '2') { event.preventDefault(); this.showCommandsDialog(); }\r\n else if (key === '3') { event.preventDefault(); this.showSettingsDialog(); }\r\n }\r\n\r\n toggleVisibility(): void {\r\n this.isVisible = !this.isVisible;\r\n this.style.display = this.isVisible ? '' : 'none';\r\n }\r\n\r\n // ── recording history (task 5) ────────────────────────────────────────────\r\n\r\n private saveRecordingHistory(): void {\r\n if (!this.cypressCommands.length) return;\r\n try {\r\n const existing = JSON.parse(localStorage.getItem('e2e-recording-history') ?? '[]');\r\n existing.unshift({ commands: this.cypressCommands, interceptors: this.interceptors, savedAt: Date.now() });\r\n if (existing.length > 5) existing.splice(5);\r\n localStorage.setItem('e2e-recording-history', JSON.stringify(existing));\r\n } catch { /* ignore storage errors */ }\r\n }\r\n\r\n recoverLastRecording(): void {\r\n try {\r\n const existing = JSON.parse(localStorage.getItem('e2e-recording-history') ?? '[]');\r\n if (!existing.length) return;\r\n const { commands, interceptors } = existing[0];\r\n commands.forEach((cmd: string) => this.recording.appendCommand(cmd));\r\n (interceptors as string[]).forEach((_icp: string) => { /* interceptors are not appendable the same way */ });\r\n } catch { /* ignore */ }\r\n }\r\n\r\n clearRecordingHistory(): void {\r\n localStorage.removeItem('e2e-recording-history');\r\n }\r\n\r\n getRecordingHistory(): Array<{ commands: string[]; interceptors: string[]; savedAt: number }> {\r\n try {\r\n return JSON.parse(localStorage.getItem('e2e-recording-history') ?? '[]');\r\n } catch { return []; }\r\n }\r\n\r\n // ── filesystem setup ─────────────────────────────────────────────────────\r\n\r\n private async initFilesystemAccess(): Promise<void> {\r\n const config = await this.persistence.getGeneralConfig();\r\n // Only show if the user has never made a choice (key doesn't exist yet)\r\n if (config && 'allowReadWriteFiles' in config) return;\r\n this.showFilesystemSetupDialog();\r\n }\r\n\r\n private showFilesystemSetupDialog(): void {\r\n Swal.fire({\r\n title: this.translation.translate('RECORDER.FS_TITLE'),\r\n html: '<div id=\"fs-setup-content\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('fs-setup-content');\r\n if (!container) return;\r\n container.innerHTML = `\r\n <div style=\"padding:16px 20px 20px;color:#8b949e;font-size:13px;line-height:1.7\">\r\n <p>${this.translation.translate('RECORDER.FS_INTRO_HTML')}</p>\r\n <p style=\"margin-top:10px;margin-bottom:6px;font-size:11px;color:#8b949e\">\r\n ${this.translation.translate('RECORDER.FS_STRUCTURE_HINT_HTML')}\r\n </p>\r\n <pre style=\"margin:0;padding:10px 14px;background:#0d1117;border:1px solid #21262d;\r\n border-radius:8px;font-size:11px;color:#c9d1d9;line-height:1.8;\r\n font-family:'Cascadia Code','Fira Code','Consolas',monospace\">\r\ncypress/ <span style=\"color:#484f58\">${this.translation.translate('RECORDER.FS_TREE_PICK_HINT')}</span>\r\n└── e2e/ <span style=\"color:#484f58\">${this.translation.translate('RECORDER.FS_TREE_READ_HINT')}</span>\r\n └── *.cy.ts</pre>\r\n <p style=\"margin-top:8px;font-size:11px;color:#484f58\">\r\n ${this.translation.translate('RECORDER.FS_PERMISSION_NOTE')}\r\n </p>\r\n <div style=\"display:flex;gap:8px;justify-content:flex-end;margin-top:20px\">\r\n <button id=\"fs-skip\"\r\n style=\"padding:7px 16px;border:1px solid #30363d;border-radius:6px;cursor:pointer;\r\n font-size:12px;font-weight:500;background:transparent;color:#8b949e\">\r\n ${this.translation.translate('RECORDER.FS_LATER_BTN')}\r\n </button>\r\n <button id=\"fs-select\"\r\n style=\"padding:7px 16px;border:none;border-radius:6px;cursor:pointer;\r\n font-size:12px;font-weight:500;background:#2f81f7;color:#fff\">\r\n ${this.translation.translate('RECORDER.FS_SELECT_BTN')}\r\n </button>\r\n </div>\r\n </div>`;\r\n\r\n document.getElementById('fs-skip')?.addEventListener('click', async () => {\r\n await this.persistence.setConfigKey('allowReadWriteFiles', 'false');\r\n Swal.close();\r\n });\r\n\r\n document.getElementById('fs-select')?.addEventListener('click', async () => {\r\n try {\r\n await this.persistence.requestDirectoryPermissions();\r\n Swal.close();\r\n showToast(this.translation.translate('RECORDER.FS_SUCCESS_TOAST'));\r\n } catch (e: unknown) {\r\n if ((e as DOMException)?.name !== 'AbortError') {\r\n showToast(this.translation.translate('RECORDER.FS_ERROR_TOAST'), false);\r\n }\r\n // AbortError = user cancelled the picker, leave dialog open\r\n }\r\n });\r\n },\r\n });\r\n }\r\n\r\n // ── dialogs ──────────────────────────────────────────────────────────────\r\n\r\n showCommandsDialog(): void {\r\n this.toggleModal('isCommandsDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.DIALOG_COMMANDS'),\r\n html: '<div id=\"commands-modal-content\" style=\"min-height:250px;padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n backdrop: false,\r\n width: 640,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n // Make the container click-through so the page underneath remains interactive\r\n const swalContainer = document.querySelector('.swal2-container') as HTMLElement | null;\r\n if (swalContainer) {\r\n swalContainer.style.pointerEvents = 'none';\r\n const popup = swalContainer.querySelector('.swal2-popup') as HTMLElement | null;\r\n if (popup) popup.style.pointerEvents = 'all';\r\n }\r\n const container = document.getElementById('commands-modal-content');\r\n if (!container) return;\r\n\r\n const child = document.createElement('test-previsualizer') as unknown as PrevisualizerEl;\r\n child.translation = this.translation;\r\n child.commands = this.cypressCommands;\r\n child.interceptors = this.interceptors;\r\n child.editable = true;\r\n container.appendChild(child as unknown as Node);\r\n this._previsualizerRef = child;\r\n\r\n child.addEventListener('deletecommand', (e: CustomEvent) => {\r\n this.recording.removeCommand(e.detail);\r\n });\r\n child.addEventListener('movecommand', (e: CustomEvent) => {\r\n this.recording.moveCommand(e.detail.from, e.detail.to);\r\n });\r\n child.addEventListener('deleteinterceptor', (e: CustomEvent) => {\r\n this.recording.removeInterceptor(e.detail);\r\n });\r\n\r\n // ── Assertion builder panel ──────────────────────────────────────\r\n const assertionHtml = `\r\n <div id=\"assertion-builder\"\r\n style=\"padding:10px 12px;border-top:1px solid #21262d;background:#0d1117\">\r\n <div style=\"font-size:10px;color:#484f58;text-transform:uppercase;letter-spacing:.8px;font-weight:600;margin-bottom:8px\">\r\n ${this.translation.translate('RECORDER.ASSERTION_SECTION')}\r\n </div>\r\n <div style=\"display:flex;gap:6px;flex-wrap:wrap;align-items:flex-end\">\r\n <input id=\"assert-selector\" type=\"text\"\r\n placeholder=\"${this.translation.translate('RECORDER.ASSERT_SELECTOR_PH').replace(/\"/g, '&quot;')}\"\r\n style=\"flex:2;min-width:140px;padding:5px 8px;background:#161b22;border:1px solid #30363d;\r\n border-radius:5px;color:#c9d1d9;font-size:11px;outline:none;\r\n font-family:'Cascadia Code','Fira Code',monospace\"/>\r\n <select id=\"assert-type\"\r\n style=\"padding:5px 8px;background:#161b22;border:1px solid #30363d;border-radius:5px;\r\n color:#c9d1d9;font-size:11px;outline:none;cursor:pointer;flex-shrink:0\">\r\n <option value=\"be.visible\">be.visible</option>\r\n <option value=\"not.exist\">not.exist</option>\r\n <option value=\"be.disabled\">be.disabled</option>\r\n <option value=\"be.checked\">be.checked</option>\r\n <option value=\"contain.text\">contain.text</option>\r\n <option value=\"have.value\">have.value</option>\r\n <option value=\"have.length\">have.length</option>\r\n <option value=\"have.class\">have.class</option>\r\n <option value=\"have.attr\">have.attr</option>\r\n </select>\r\n <input id=\"assert-value\" type=\"text\" placeholder=\"${this.translation.translate('RECORDER.ASSERT_VALUE_PH')}\"\r\n style=\"flex:2;min-width:110px;padding:5px 8px;background:#161b22;border:1px solid #30363d;\r\n border-radius:5px;color:#c9d1d9;font-size:11px;outline:none\"/>\r\n <button id=\"btn-add-assertion\"\r\n style=\"padding:5px 12px;border:none;border-radius:5px;cursor:pointer;\r\n font-size:11px;font-weight:500;background:#2f81f7;color:#fff;\r\n white-space:nowrap;flex-shrink:0\">\r\n ${this.translation.translate('RECORDER.ASSERT_ADD_BTN')}\r\n </button>\r\n </div>\r\n </div>`;\r\n container.insertAdjacentHTML('beforeend', assertionHtml);\r\n\r\n const NO_VALUE_ASSERTIONS = new Set(['be.visible', 'not.exist', 'be.disabled', 'be.checked']);\r\n document.getElementById('btn-add-assertion')?.addEventListener('click', () => {\r\n const sel = (document.getElementById('assert-selector') as HTMLInputElement).value.trim();\r\n const type = (document.getElementById('assert-type') as HTMLSelectElement).value;\r\n const val = (document.getElementById('assert-value') as HTMLInputElement).value.trim();\r\n if (!sel) return;\r\n const cmd = NO_VALUE_ASSERTIONS.has(type) || !val\r\n ? `cy.get('${sel}').should('${type}')`\r\n : `cy.get('${sel}').should('${type}', '${val}')`;\r\n this.recording.appendCommand(cmd);\r\n (document.getElementById('assert-selector') as HTMLInputElement).value = '';\r\n (document.getElementById('assert-value') as HTMLInputElement).value = '';\r\n });\r\n },\r\n willClose: () => {\r\n this.isCommandsDialogOpen = false;\r\n this._previsualizerRef = null;\r\n },\r\n });\r\n this.resizePopup();\r\n });\r\n }\r\n\r\n showSavedTestsDialog(): void {\r\n this.toggleModal('isSavedTestsDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.DIALOG_SAVED_TESTS'),\r\n html: '<div id=\"saved-tests-modal-content\" style=\"min-height:250px;padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n width: 680,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('saved-tests-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('test-editor') as unknown as TestEditorEl;\r\n child.persistence = this.persistence;\r\n child.translation = this.translation;\r\n container.appendChild(child as unknown as Node);\r\n },\r\n willClose: () => { this.isSavedTestsDialogOpen = false; },\r\n });\r\n this.resizePopup();\r\n });\r\n }\r\n\r\n showSaveTestDialog(): void {\r\n this.toggleModal('isSaveTestDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.DIALOG_SAVE'),\r\n html: '<div id=\"save-test-modal-content\" style=\"padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('save-test-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('save-test') as unknown as SaveTestEl;\r\n child.translation = this.translation;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('savetest', (e: CustomEvent) => {\r\n const { description, notes, tags } = e.detail ?? {};\r\n this.onSaveTest(description ?? null, tags ?? [], notes ?? '');\r\n Swal.close();\r\n });\r\n child.addEventListener('saveandexport', (e: CustomEvent) => {\r\n const { description, notes, tags } = e.detail ?? {};\r\n this.onSaveAndExportTest(description ?? null, tags ?? [], notes ?? '');\r\n Swal.close();\r\n });\r\n },\r\n willClose: () => { this.isSaveTestDialogOpen = false; },\r\n });\r\n });\r\n }\r\n\r\n showSettingsDialog(): void {\r\n this.toggleModal('isSettingsDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.SETTINGS'),\r\n html: '<div id=\"settings-modal-content\" style=\"padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n width: 520,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('settings-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('e2e-configuration') as unknown as ConfigEl;\r\n child.persistence = this.persistence;\r\n child.translation = this.translation;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('smartselectorchange', (e: CustomEvent) => {\r\n this.smartSelectorEnabled = e.detail;\r\n });\r\n child.addEventListener('starthiddenchange', (e: CustomEvent) => {\r\n this.isVisible = !e.detail;\r\n this.style.display = this.isVisible ? '' : 'none';\r\n });\r\n },\r\n willClose: () => { this.isSettingsDialogOpen = false; },\r\n });\r\n this.resizePopup();\r\n });\r\n }\r\n\r\n showAdvancedEditorDialog(testId?: number): void {\r\n this.toggleModal('isAdvancedEditorDialogOpen', () => {\r\n Swal.fire({\r\n title: this.translation.translate('MAIN_FRAME.SHOW_ADVANCED_EDITOR'),\r\n html: '<div id=\"advanced-editor-modal-content\" style=\"flex:1;min-height:0;display:flex;flex-direction:column;padding:0\"></div>',\r\n showCloseButton: true,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n width: 780,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const popup = Swal.getPopup();\r\n if (popup) {\r\n popup.style.height = '600px';\r\n const htmlContainer = popup.querySelector('.swal2-html-container') as HTMLElement | null;\r\n if (htmlContainer) {\r\n htmlContainer.style.flex = '1';\r\n htmlContainer.style.minHeight = '0';\r\n htmlContainer.style.overflow = 'hidden';\r\n htmlContainer.style.padding = '0';\r\n htmlContainer.style.margin = '0';\r\n htmlContainer.style.display = 'flex';\r\n htmlContainer.style.flexDirection = 'column';\r\n }\r\n }\r\n const container = document.getElementById('advanced-editor-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('advanced-test-editor') as unknown as AdvancedEditorEl;\r\n child.persistence = this.persistence;\r\n child.translation = this.translation;\r\n if (testId !== undefined) child.testId = testId;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('selectorstrategychange', (e: CustomEvent) => {\r\n this.recording.selectorStrategy = e.detail;\r\n });\r\n child.addEventListener('closemodal', () => Swal.close());\r\n child.addEventListener('openfileeditor', (e: CustomEvent) => {\r\n Swal.close();\r\n setTimeout(() => this.showFileEditorDialog(\r\n e.detail.handle, e.detail.content, e.detail.fileName, e.detail.testId,\r\n e.detail.itBlock, e.detail.interceptorsBlock,\r\n ), 150);\r\n });\r\n },\r\n willClose: () => { this.isAdvancedEditorDialogOpen = false; },\r\n });\r\n setTimeout(() => {\r\n const popup = Swal.getPopup();\r\n if (popup) makeModalResizable(popup, { minWidth: 400, minHeight: 0 });\r\n }, 0);\r\n });\r\n }\r\n\r\n private showFileEditorDialog(\r\n handle: FileSystemFileHandle,\r\n content: string,\r\n fileName: string,\r\n testId?: number,\r\n itBlock = '',\r\n interceptorsBlock = '',\r\n ): void {\r\n Swal.fire({\r\n title: this.translation.translate('RECORDER.FILE_EDITOR_TITLE'),\r\n html: '<div id=\"file-editor-modal-content\" style=\"padding:0;height:540px\"></div>',\r\n showCloseButton: false,\r\n showConfirmButton: false,\r\n allowOutsideClick: false,\r\n width: 1100,\r\n color: '#e6edf3',\r\n didOpen: () => {\r\n makeSwalDraggable();\r\n setSwal2DataCyAttribute();\r\n const container = document.getElementById('file-editor-modal-content');\r\n if (!container) return;\r\n const child = document.createElement('file-preview') as unknown as FilePreviewEl;\r\n child.translation = this.translation;\r\n child.fileContent = content;\r\n child.fileName = fileName;\r\n child.closeLabel = this.translation.translate('FILE_PREVIEW.BACK_TO_EDITOR');\r\n child.itBlock = itBlock;\r\n child.interceptorsBlock = interceptorsBlock;\r\n container.appendChild(child as unknown as Node);\r\n child.addEventListener('close', () => {\r\n Swal.close();\r\n setTimeout(() => this.showAdvancedEditorDialog(testId), 150);\r\n });\r\n child.addEventListener('save', async (e: CustomEvent) => {\r\n try {\r\n const writable = await handle.createWritable();\r\n await writable.write(e.detail);\r\n await writable.close();\r\n showToast(this.translation.translate('RECORDER.FILE_SAVED_TOAST'));\r\n } catch {\r\n showToast(this.translation.translate('RECORDER.FILE_SAVE_ERROR_TOAST'), false);\r\n }\r\n Swal.close();\r\n setTimeout(() => this.showAdvancedEditorDialog(testId), 150);\r\n });\r\n },\r\n });\r\n this.resizePopup();\r\n }\r\n\r\n // ── save handlers ─────────────────────────────────────────────────────────\r\n\r\n private async onSaveTest(description: string | null, tags: string[] = [], notes = ''): Promise<void> {\r\n if (description) {\r\n await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags, notes);\r\n this.recording.clearCommands();\r\n this.clearRecordingHistory();\r\n this.cypressCommands = [];\r\n this.interceptors = [];\r\n }\r\n }\r\n\r\n private async onSaveAndExportTest(description: string | null, tags: string[] = [], notes = ''): Promise<void> {\r\n if (description) {\r\n const id = await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags, notes);\r\n this.recording.clearCommands();\r\n this.clearRecordingHistory();\r\n this.cypressCommands = [];\r\n this.interceptors = [];\r\n setTimeout(() => this.showAdvancedEditorDialog(id), 300);\r\n }\r\n }\r\n\r\n // ── helpers ───────────────────────────────────────────────────────────────\r\n\r\n private toggleModal(flag: keyof this, openFn: () => void): void {\r\n if (this[flag]) {\r\n Swal.close();\r\n (this as Record<string, unknown>)[flag as string] = false;\r\n return;\r\n }\r\n (this as Record<string, unknown>)[flag as string] = true;\r\n openFn();\r\n }\r\n\r\n private resizePopup(): void {\r\n setTimeout(() => {\r\n const popup = Swal.getPopup();\r\n if (popup) makeModalResizable(popup, { minWidth: 400, minHeight: 200 });\r\n }, 0);\r\n }\r\n\r\n private render(): void {\r\n const rec = this.isRecording;\r\n const paused = this.isPaused;\r\n this.style.display = this.isVisible ? '' : 'none';\r\n this.shadow.innerHTML = `<style>${getRecorderStyles(rec, paused)}</style>${renderRecorderWidget(rec, paused, this.translation.translate.bind(this.translation))}`;\r\n this.shadow.querySelector('[data-action=\"toggle\"]')\r\n ?.addEventListener('click', () => this.toggle());\r\n this.shadow.querySelector('[data-action=\"pause\"]')\r\n ?.addEventListener('click', () => this.togglePause());\r\n this.shadow.querySelector('[data-action=\"tests\"]')\r\n ?.addEventListener('click', () => this.showSavedTestsDialog());\r\n this.shadow.querySelector('[data-action=\"commands\"]')\r\n ?.addEventListener('click', () => this.showCommandsDialog());\r\n this.shadow.querySelector('[data-action=\"config\"]')\r\n ?.addEventListener('click', () => this.showSettingsDialog());\r\n this.shadow.querySelector('[data-action=\"browse\"]')\r\n ?.addEventListener('click', () => this.showAdvancedEditorDialog());\r\n }\r\n}\r\n\r\nif (!customElements.get('lib-e2e-recorder')) {\r\n customElements.define('lib-e2e-recorder', LibE2eRecorderElement);\r\n}\r\n","export function getRecorderStyles(rec: boolean, paused: boolean): string {\n return `\n :host { all: initial; }\n *, *::before, *::after { box-sizing: border-box; }\n\n /*\n * Invisible 190×190 hit area anchored at bottom-right.\n * Keeps :hover alive while the cursor travels from the\n * toggle to any of the radial action buttons.\n */\n .widget {\n position: fixed;\n bottom: 0;\n right: 0;\n width: 190px;\n height: 190px;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n }\n\n /* ── Toggle ──────────────────────────────────────── */\n .btn-toggle {\n position: absolute;\n bottom: 24px;\n right: 24px;\n width: 44px;\n height: 44px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n font-size: 19px;\n background: ${rec\n ? 'linear-gradient(135deg,#f85149 0%,#da3633 100%)'\n : 'linear-gradient(135deg,#2f81f7 0%,#1f6feb 100%)'};\n color: #fff;\n box-shadow: ${rec\n ? '0 4px 20px rgba(248,81,73,.55),0 0 0 4px rgba(248,81,73,.13)'\n : '0 4px 20px rgba(47,129,247,.45),0 0 0 4px rgba(47,129,247,.11)'};\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform .18s, box-shadow .2s;\n z-index: 2;\n ${rec ? 'animation: toggle-pulse 2s ease-in-out infinite;' : ''}\n }\n .btn-toggle:hover { transform: scale(1.1); }\n .btn-toggle:active { transform: scale(0.93); }\n\n @keyframes toggle-pulse {\n 0%,100% { box-shadow: 0 4px 20px rgba(248,81,73,.55),0 0 0 4px rgba(248,81,73,.13); }\n 50% { box-shadow: 0 6px 28px rgba(248,81,73,.75),0 0 0 8px rgba(248,81,73,.06); }\n }\n\n /* ── Pause button ────────────────────────────────── */\n .btn-pause {\n position: absolute;\n bottom: 78px;\n right: 24px;\n width: 34px;\n height: 34px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n font-size: 15px;\n display: ${rec ? 'flex' : 'none'};\n align-items: center;\n justify-content: center;\n background: ${paused\n ? 'linear-gradient(135deg,#2f81f7 0%,#1f6feb 100%)'\n : 'rgba(13,17,23,0.85)'};\n color: ${paused ? '#fff' : '#e3b341'};\n box-shadow: 0 2px 12px rgba(0,0,0,.4), 0 0 0 1px rgba(48,54,61,.8);\n transition: transform .15s, background .2s, color .2s;\n z-index: 2;\n }\n .btn-pause:hover { transform: scale(1.12); }\n .btn-pause:active { transform: scale(0.93); }\n\n /* ── Action buttons ──────────────────────────────── */\n /*\n * All three start centered on the toggle button\n * (toggle center = bottom:46px right:46px from widget edge;\n * button half = 18px → bottom:28px right:28px).\n */\n .btn-action {\n position: absolute;\n bottom: 28px;\n right: 28px;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n cursor: pointer;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(13,17,23,.92);\n backdrop-filter: blur(14px);\n -webkit-backdrop-filter: blur(14px);\n color: #8b949e;\n box-shadow: 0 4px 18px rgba(0,0,0,.45), 0 0 0 1px rgba(48,54,61,.75);\n opacity: 0;\n transform: scale(0.35);\n pointer-events: none;\n /* Collapse: fast, no spring */\n transition: opacity .15s, transform .18s ease-in,\n background .15s, color .12s, box-shadow .15s;\n }\n\n /* Label to the left of each button */\n .btn-action::after {\n content: attr(data-label);\n position: absolute;\n right: calc(100% + 9px);\n top: 50%;\n transform: translateY(-50%);\n background: rgba(13,17,23,.95);\n color: #e6edf3;\n font-size: 11px;\n font-weight: 500;\n padding: 3px 9px;\n border-radius: 6px;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity .15s .05s;\n border: 1px solid rgba(48,54,61,.8);\n box-shadow: 0 2px 8px rgba(0,0,0,.35);\n }\n /* Button 1 (top) — label above instead of left to avoid overlap with btn 2 */\n .btn-action[data-n=\"1\"]::after {\n right: auto;\n left: 50%;\n top: auto;\n bottom: calc(100% + 9px);\n transform: translateX(-50%);\n }\n .btn-action:hover::after { opacity: 1; }\n .btn-action:hover { background: #21262d; color: #e6edf3; }\n .btn-action:active { background: #30363d !important; }\n\n /* Expand: spring + stagger */\n .widget:hover .btn-action {\n opacity: 1;\n pointer-events: all;\n transition: opacity .2s, transform .32s cubic-bezier(.34,1.56,.64,1),\n background .15s, color .12s, box-shadow .15s;\n }\n\n /* Arc positions — 4 buttons, 30° spacing, radius 90px */\n .widget:hover .btn-action[data-n=\"1\"] { /* 0° — straight up */\n transform: translateY(-90px) scale(1);\n transition-delay: .03s;\n }\n .widget:hover .btn-action[data-n=\"2\"] { /* 30° — upper-left */\n transform: translate(-45px,-78px) scale(1);\n transition-delay: .07s;\n }\n .widget:hover .btn-action[data-n=\"3\"] { /* 60° — left-upper */\n transform: translate(-78px,-45px) scale(1);\n transition-delay: .11s;\n }\n .widget:hover .btn-action[data-n=\"4\"] { /* 90° — straight left */\n transform: translateX(-90px) scale(1);\n transition-delay: .15s;\n }\n /* Button 4 (pure left) — label above to avoid going off-screen */\n .btn-action[data-n=\"4\"]::after {\n right: auto;\n left: 50%;\n top: auto;\n bottom: calc(100% + 9px);\n transform: translateX(-50%);\n }\n\n /* ── REC / PAUSED badge ──────────────────────────── */\n .rec-badge {\n position: fixed;\n top: 14px;\n left: 50%;\n transform: translateX(-50%);\n background: ${paused\n ? 'linear-gradient(90deg,#e3b341,#d29922)'\n : 'linear-gradient(90deg,#f85149,#da3633)'};\n color: #fff;\n padding: 3px 16px;\n border-radius: 20px;\n font-size: 10px;\n font-weight: 700;\n letter-spacing: 2px;\n text-transform: uppercase;\n z-index: 2147483647;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: ${paused\n ? '0 4px 16px rgba(227,179,65,.4)'\n : '0 4px 16px rgba(248,81,73,.4)'};\n display: ${rec ? 'block' : 'none'};\n ${!paused ? 'animation: rec-pulse 1.8s ease-in-out infinite;' : ''}\n }\n @keyframes rec-pulse {\n 0%,100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n `;\n}\n","export function renderRecorderWidget(rec: boolean, paused: boolean, t: (key: string) => string): string {\n return `\n <div class=\"widget\">\n <button class=\"btn-action\" data-n=\"1\" data-action=\"config\"\n data-label=\"${t('RECORDER.BTN_CONFIG')}\">⚙️</button>\n <button class=\"btn-action\" data-n=\"2\" data-action=\"browse\"\n data-label=\"${t('RECORDER.BTN_FILES')}\">📁</button>\n <button class=\"btn-action\" data-n=\"3\" data-action=\"commands\"\n data-label=\"${t('RECORDER.BTN_COMMANDS')}\">⌨️</button>\n <button class=\"btn-action\" data-n=\"4\" data-action=\"tests\"\n data-label=\"${t('RECORDER.BTN_TESTS')}\">📋</button>\n <button class=\"btn-pause\" data-action=\"pause\"\n title=\"${paused ? t('RECORDER.RESUME_TITLE') : t('RECORDER.PAUSE_TITLE')}\">\n ${paused ? '▶' : '⏸'}\n </button>\n <button class=\"btn-toggle\" data-action=\"toggle\"\n title=\"${rec ? t('RECORDER.STOP_TITLE') : t('RECORDER.START_TITLE')}\">\n ${rec ? '⏹' : '⏺'}\n </button>\n </div>\n <div class=\"rec-badge\">${paused ? t('RECORDER.BADGE_PAUSED') : t('RECORDER.BADGE_REC')}</div>`;\n}\n","// Public API — populated as migration phases are completed\r\nexport const VERSION = '0.1.0';\r\n\r\n// Phase 1 — Models\r\nexport * from './models/lang.model';\r\nexport * from './models/input-types.model';\r\nexport * from './models/db-schema.model';\r\n\r\n// Phase 2 — TranslationService\r\nexport * from './services/translation.service';\r\n\r\n// Phase 3 — Transformation Services\r\nexport * from './services/transformation.service';\r\nexport * from './services/advanced-test.transformation.service';\r\n\r\n// Phase 4 — RecordingService\r\nexport * from './utils/subject';\r\nexport * from './services/recording.service';\r\n\r\n// Phase 5 — PersistenceService\r\nexport * from './services/persistence.service';\r\n\r\n// Phase 6 — HttpMonitor\r\nexport * from './services/http-monitor';\r\n\r\n// Phase 7 — UI Utilities\r\nexport * from './utils/styles.utils';\r\nexport * from './utils/modal.utils';\r\nexport * from './utils/toast.utils';\r\n\r\n// Phase 8 — Web Components\r\nexport * from './components/test-previsualizer/test-previsualizer';\r\nexport * from './components/save-test/save-test';\r\nexport * from './components/test-editor/test-editor';\r\nexport * from './components/configuration/configuration';\r\nexport * from './components/advanced-test-editor/advanced-test-editor';\r\nexport * from './components/file-preview/file-preview';\r\nexport * from './components/lib-e2e-recorder/lib-e2e-recorder';\r\n"],"mappings":"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","names":["tag","container","rect","input","i","j"]}