lib-e2e-cypress-for-dummys-ts 1.0.0 → 1.1.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.
@@ -0,0 +1,2279 @@
1
+ // src/utils/code-format.utils.ts
2
+ function gcd(a, b) {
3
+ while (b) {
4
+ const t = b;
5
+ b = a % b;
6
+ a = t;
7
+ }
8
+ return a;
9
+ }
10
+ function escapeSingleQuotes(value) {
11
+ return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
12
+ }
13
+ function selectorLiteral(selector) {
14
+ if (selector.includes("'")) {
15
+ return `"${selector.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
16
+ }
17
+ return `'${escapeSingleQuotes(selector)}'`;
18
+ }
19
+ function escapeCssAttrValue(value) {
20
+ return value.replace(/"/g, '\\"');
21
+ }
22
+ function normalizeBlock(code, baseIndent) {
23
+ const lines = code.split("\n").map((l) => l.trimEnd());
24
+ const nonEmpty = lines.filter((l) => l.trim().length > 0);
25
+ if (!nonEmpty.length) return "";
26
+ const indents = nonEmpty.map((l) => l.length - l.trimStart().length);
27
+ const minIndent = Math.min(...indents);
28
+ const relIndents = [...new Set(indents.map((n) => n - minIndent).filter((n) => n > 0))];
29
+ const step = relIndents.length > 0 ? relIndents.reduce(gcd) : 2;
30
+ return lines.map((l) => {
31
+ if (!l.trim()) return "";
32
+ const level = Math.round((l.length - l.trimStart().length - minIndent) / step);
33
+ return baseIndent + " ".repeat(level) + l.trimStart();
34
+ }).join("\n");
35
+ }
36
+
37
+ // src/utils/selector-quality.utils.ts
38
+ var FORBIDDEN_ID_PREFIXES = [
39
+ "cdk-",
40
+ "mat-",
41
+ "p-",
42
+ "ng-",
43
+ "mdc-",
44
+ "primeng-",
45
+ "auto-",
46
+ "field-",
47
+ "input-",
48
+ "select-"
49
+ ];
50
+ function getSelectorQuality(el) {
51
+ if (el.hasAttribute("data-cy") || el.hasAttribute("data-testid") || el.hasAttribute("aria-label")) {
52
+ return "excellent";
53
+ }
54
+ const rawId = el.id;
55
+ if (rawId && rawId.length < 25 && /^[a-zA-Z][\w-]*$/.test(rawId) && !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) && !/^\d+$/.test(rawId)) {
56
+ return "good";
57
+ }
58
+ if (typeof el.className === "string" && el.className.trim().length > 0) {
59
+ return "acceptable";
60
+ }
61
+ return "poor";
62
+ }
63
+ function buildPickerSelector(el) {
64
+ const dataCy = el.getAttribute("data-cy");
65
+ if (dataCy) return `[data-cy="${escapeCssAttrValue(dataCy)}"]`;
66
+ const dataTestid = el.getAttribute("data-testid");
67
+ if (dataTestid) return `[data-testid="${escapeCssAttrValue(dataTestid)}"]`;
68
+ const ariaLabel = el.getAttribute("aria-label");
69
+ if (ariaLabel) return `[aria-label="${escapeCssAttrValue(ariaLabel)}"]`;
70
+ const rawId = el.id;
71
+ if (rawId && rawId.length < 25 && /^[a-zA-Z][\w-]*$/.test(rawId) && !FORBIDDEN_ID_PREFIXES.some((p) => rawId.startsWith(p)) && !/^\d+$/.test(rawId)) {
72
+ return `#${rawId}`;
73
+ }
74
+ if (typeof el.className === "string" && el.className.trim().length > 0) {
75
+ const classes = el.className.trim().split(/\s+/);
76
+ return classes.map((c) => `.${c}`).join("");
77
+ }
78
+ return el.tagName.toLowerCase();
79
+ }
80
+ function keyAttrDisplay(el) {
81
+ for (const attr of ["data-cy", "data-testid", "aria-label"]) {
82
+ const v = el.getAttribute(attr);
83
+ if (v) return `${attr}="${v}"`;
84
+ }
85
+ if (el.id) return `id="${el.id}"`;
86
+ if (el.className && el.className.trim()) {
87
+ return el.className.trim().split(/\s+/).map((c) => `.${c}`).join("");
88
+ }
89
+ return "";
90
+ }
91
+ function describePickerRow(el) {
92
+ return {
93
+ quality: getSelectorQuality(el),
94
+ selector: buildPickerSelector(el),
95
+ tag: el.tagName.toLowerCase(),
96
+ attr: keyAttrDisplay(el)
97
+ };
98
+ }
99
+
100
+ // src/utils/theme.ts
101
+ var THEME = {
102
+ color: {
103
+ // ── Backgrounds ─────────────────────────────────────────────────────────
104
+ /** Darkest surface: inputs, code blocks, sidebar. */
105
+ bgInput: "#0d1117",
106
+ /** Panel / card surface. */
107
+ bgCard: "#161b22",
108
+ // ── Borders ─────────────────────────────────────────────────────────────
109
+ /** Subtle border (default, non-interactive). */
110
+ border: "#21262d",
111
+ /** Muted border on hover, also used as scrollbar thumb colour. */
112
+ borderHover: "#30363d",
113
+ // ── Text ────────────────────────────────────────────────────────────────
114
+ /** Dimmed text: placeholders, empty states, timestamps. */
115
+ textMuted: "#484f58",
116
+ /** Secondary labels, icon buttons, helper text. */
117
+ textSecondary: "#8b949e",
118
+ /** Body text, code. */
119
+ textBody: "#c9d1d9",
120
+ /** Primary headings and prominent text. */
121
+ textPrimary: "#e6edf3",
122
+ // ── Accents — blue ──────────────────────────────────────────────────────
123
+ /** Primary interactive accent. */
124
+ blue: "#2f81f7",
125
+ /** Darker blue for hover / gradient end. */
126
+ blueDark: "#1f6feb",
127
+ /** Lighter blue for selection outlines. */
128
+ blueLight: "#388bfd",
129
+ // ── Accents — green ─────────────────────────────────────────────────────
130
+ /** Success / "new file" button. */
131
+ green: "#238636",
132
+ /** Green hover state. */
133
+ greenHover: "#2ea043",
134
+ /** Lighter green for save buttons and diff additions. */
135
+ greenLight: "#3fb950",
136
+ // ── Accents — red ───────────────────────────────────────────────────────
137
+ /** Danger / error. */
138
+ red: "#f85149",
139
+ /** Darker red for gradient end (recording button). */
140
+ redDark: "#da3633",
141
+ // ── Accents — yellow / amber ────────────────────────────────────────────
142
+ /** Ticket badges, paused state. */
143
+ yellow: "#d29922",
144
+ /** Lighter amber (paused badge, launch button). */
145
+ yellowLight: "#e3b341",
146
+ /** Darker amber (folder-button border/hover). */
147
+ yellowDark: "#9e6a03",
148
+ // ── Accents — purple ────────────────────────────────────────────────────
149
+ /** Insert / special action button. */
150
+ purple: "#a371f7",
151
+ // ── Syntax highlighting ─────────────────────────────────────────────────
152
+ shKeyword: "#ff7b72",
153
+ shBuiltin: "#d2a8ff",
154
+ shString: "#a5d6ff",
155
+ /** Alternate string colour (interceptor code blocks). */
156
+ shStringAlt: "#85e89d",
157
+ shNumber: "#79c0ff",
158
+ /** Selector preview in the picker. */
159
+ shSelector: "#58a6ff"
160
+ },
161
+ zIndex: {
162
+ /** Full-viewport overlay: selector-picker host, recorder FAB, REC badge. */
163
+ overlay: 2147483647,
164
+ /** In-widget modal (export panel, login-setup panel). */
165
+ modal: 1e5,
166
+ /** SweetAlert2 container override. */
167
+ swal2: 99999
168
+ }
169
+ };
170
+ function scrollbar(selector, size = 4) {
171
+ const c = THEME.color.borderHover;
172
+ return `
173
+ ${selector} { scrollbar-width: thin; scrollbar-color: ${c} transparent; }
174
+ ${selector}::-webkit-scrollbar { width: ${size}px; height: ${size}px; }
175
+ ${selector}::-webkit-scrollbar-thumb { background: ${c}; border-radius: 2px; }`;
176
+ }
177
+ var SCROLLBAR_INLINE = `scrollbar-width: thin; scrollbar-color: ${THEME.color.borderHover} transparent;`;
178
+
179
+ // src/components/selector-picker/selector-picker.styles.ts
180
+ var SELECTOR_PICKER_STYLES = `
181
+ :host {
182
+ position: fixed;
183
+ z-index: ${THEME.zIndex.overlay};
184
+ top: 0;
185
+ left: 0;
186
+ width: 100vw;
187
+ height: 100vh;
188
+ pointer-events: none;
189
+ }
190
+
191
+ .overlay {
192
+ position: absolute;
193
+ top: 50%;
194
+ left: 50%;
195
+ transform: translate(-50%, -50%);
196
+ pointer-events: all;
197
+ background: ${THEME.color.bgCard};
198
+ border: 1px solid ${THEME.color.borderHover};
199
+ border-radius: 10px;
200
+ box-shadow: 0 8px 32px rgba(0,0,0,0.6);
201
+ min-width: 420px;
202
+ max-width: 600px;
203
+ font-family: 'Segoe UI', system-ui, sans-serif;
204
+ color: ${THEME.color.textPrimary};
205
+ font-size: 13px;
206
+ }
207
+
208
+ .header {
209
+ padding: 12px 16px 8px;
210
+ border-bottom: 1px solid ${THEME.color.border};
211
+ font-weight: 600;
212
+ font-size: 13px;
213
+ color: ${THEME.color.textSecondary};
214
+ letter-spacing: 0.04em;
215
+ text-transform: uppercase;
216
+ }
217
+
218
+ .list {
219
+ max-height: 320px;
220
+ overflow-y: auto;
221
+ padding: 6px 0;
222
+ }
223
+
224
+ .row {
225
+ display: flex;
226
+ align-items: center;
227
+ gap: 8px;
228
+ padding: 7px 14px;
229
+ cursor: pointer;
230
+ border-radius: 6px;
231
+ margin: 1px 6px;
232
+ transition: background 0.1s;
233
+ }
234
+
235
+ .row:hover,
236
+ .row.selected {
237
+ background: ${THEME.color.border};
238
+ }
239
+
240
+ .row.selected {
241
+ outline: 2px solid ${THEME.color.blueLight};
242
+ outline-offset: -2px;
243
+ }
244
+
245
+ .quality-badge {
246
+ width: 18px;
247
+ height: 18px;
248
+ border-radius: 50%;
249
+ flex-shrink: 0;
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ font-size: 10px;
254
+ }
255
+
256
+ .badge-excellent { background: ${THEME.color.green}; }
257
+ .badge-good { background: ${THEME.color.blueDark}; }
258
+ .badge-acceptable{ background: ${THEME.color.yellowDark}; }
259
+ .badge-poor { background: ${THEME.color.redDark}; }
260
+
261
+ .tag-name {
262
+ font-family: monospace;
263
+ font-size: 12px;
264
+ color: ${THEME.color.textSecondary};
265
+ flex-shrink: 0;
266
+ }
267
+
268
+ .attr-value {
269
+ font-family: monospace;
270
+ font-size: 12px;
271
+ color: ${THEME.color.textBody};
272
+ flex: 1;
273
+ overflow: hidden;
274
+ text-overflow: ellipsis;
275
+ white-space: nowrap;
276
+ }
277
+
278
+ .selector-preview {
279
+ font-family: monospace;
280
+ font-size: 11px;
281
+ color: ${THEME.color.shSelector};
282
+ flex-shrink: 0;
283
+ max-width: 180px;
284
+ overflow: hidden;
285
+ text-overflow: ellipsis;
286
+ white-space: nowrap;
287
+ }
288
+
289
+ .poor-warning {
290
+ font-size: 10px;
291
+ color: ${THEME.color.red};
292
+ margin-left: auto;
293
+ }
294
+
295
+ .footer {
296
+ padding: 8px 14px 10px;
297
+ border-top: 1px solid ${THEME.color.border};
298
+ display: flex;
299
+ gap: 16px;
300
+ font-size: 11px;
301
+ color: ${THEME.color.textMuted};
302
+ }
303
+
304
+ .hint kbd {
305
+ background: ${THEME.color.border};
306
+ border: 1px solid ${THEME.color.borderHover};
307
+ border-radius: 3px;
308
+ padding: 1px 5px;
309
+ font-size: 10px;
310
+ color: ${THEME.color.textSecondary};
311
+ }
312
+ `;
313
+
314
+ // src/utils/html.utils.ts
315
+ function escHtml(s) {
316
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
317
+ }
318
+ function escAttr(s) {
319
+ return s.replace(/"/g, "&quot;").replace(/</g, "&lt;");
320
+ }
321
+
322
+ // src/components/selector-picker/selector-picker.template.ts
323
+ var QUALITY_EMOJI = {
324
+ excellent: "\u{1F7E2}",
325
+ good: "\u{1F535}",
326
+ acceptable: "\u{1F7E1}",
327
+ poor: "\u{1F534}"
328
+ };
329
+ var QUALITY_CLASS = {
330
+ excellent: "badge-excellent",
331
+ good: "badge-good",
332
+ acceptable: "badge-acceptable",
333
+ poor: "badge-poor"
334
+ };
335
+ function renderPickerRows(rows, selectedIndex, t) {
336
+ return rows.map((row, i) => {
337
+ const isSelected = i === selectedIndex;
338
+ const isPoor = row.quality === "poor";
339
+ return `
340
+ <div class="row${isSelected ? " selected" : ""}" data-idx="${i}" role="option" aria-selected="${isSelected}">
341
+ <span class="quality-badge ${QUALITY_CLASS[row.quality]}" title="${escHtml(t(`SELECTOR_PICKER.QUALITY_${row.quality.toUpperCase()}`))}">
342
+ ${QUALITY_EMOJI[row.quality]}
343
+ </span>
344
+ <span class="tag-name">&lt;${escHtml(row.tag)}&gt;</span>
345
+ ${row.attr ? `<span class="attr-value">${escHtml(row.attr)}</span>` : '<span class="attr-value"></span>'}
346
+ <span class="selector-preview">${escHtml(row.selector)}</span>
347
+ ${isPoor ? `<span class="poor-warning" title="${escHtml(t("SELECTOR_PICKER.QUALITY_POOR"))}">\u26A0</span>` : ""}
348
+ </div>`;
349
+ }).join("");
350
+ }
351
+ function renderPicker(rows, selectedIndex, t) {
352
+ return `
353
+ <div class="overlay" role="listbox">
354
+ <div class="header">${escHtml(t("SELECTOR_PICKER.TITLE"))}</div>
355
+ <div class="list">
356
+ ${renderPickerRows(rows, selectedIndex, t)}
357
+ </div>
358
+ <div class="footer">
359
+ <span class="hint"><kbd>\u2191\u2193</kbd> ${escHtml(t("SELECTOR_PICKER.PREVIEW_LABEL"))}</span>
360
+ <span class="hint"><kbd>Enter</kbd> ${escHtml(t("SELECTOR_PICKER.CONFIRM_HINT"))}</span>
361
+ <span class="hint"><kbd>Esc</kbd> ${escHtml(t("SELECTOR_PICKER.CANCEL_HINT"))}</span>
362
+ </div>
363
+ </div>`;
364
+ }
365
+
366
+ // src/models/lang.model.ts
367
+ var SUPPORTED_LANGS = ["es", "en", "fr", "it", "de"];
368
+ function isLang(value) {
369
+ return SUPPORTED_LANGS.includes(value);
370
+ }
371
+ var LOCALE_BY_LANG = {
372
+ es: "es-ES",
373
+ en: "en-GB",
374
+ fr: "fr-FR",
375
+ it: "it-IT",
376
+ de: "de-DE"
377
+ };
378
+ function localeForLang(lang) {
379
+ return isLang(lang) ? LOCALE_BY_LANG[lang] : "es-ES";
380
+ }
381
+
382
+ // src/utils/subject.ts
383
+ var Subject = class {
384
+ _value;
385
+ listeners = /* @__PURE__ */ new Set();
386
+ constructor(initialValue) {
387
+ this._value = initialValue;
388
+ }
389
+ next(value) {
390
+ this._value = value;
391
+ this.listeners.forEach((l) => l(value));
392
+ }
393
+ getValue() {
394
+ return this._value;
395
+ }
396
+ subscribe(fn) {
397
+ this.listeners.add(fn);
398
+ return () => this.listeners.delete(fn);
399
+ }
400
+ };
401
+
402
+ // src/i18n/es.ts
403
+ var I18N_ES = {
404
+ MAIN_FRAME: {
405
+ SETTINGS: "Configuraci\xF3n",
406
+ SHOW_ADVANCED_EDITOR: "Editor avanzado",
407
+ DIALOG_SAVED_TESTS: "Pruebas guardadas",
408
+ DIALOG_COMMANDS: "Previsualizador de comandos Cypress",
409
+ DIALOG_SAVE: "\xBFGuardar la grabaci\xF3n?"
410
+ },
411
+ SAVE_TEST: {
412
+ DESC_LABEL: "Descripci\xF3n de la prueba",
413
+ CANCEL: "Cancelar",
414
+ ASK: "\xBFGuardar el test grabado?",
415
+ YES_CONTINUE: "S\xED, continuar",
416
+ NO_DISCARD: "No, descartar",
417
+ DESC_PLACEHOLDER: "Ej: Login correcto con credenciales v\xE1lidas",
418
+ TAGS_LABEL: "Etiquetas (opcional, para filtrar despu\xE9s):",
419
+ TAGS_PLACEHOLDER: "smoke, login, regresi\xF3n\u2026",
420
+ ADD_TAG: "+ A\xF1adir",
421
+ NO_TAGS: "Sin etiquetas",
422
+ SAVE_BTN: "\u{1F4BE} Guardar",
423
+ SAVE_AND_EDIT: "\u{1F4DD} Guardar y editar",
424
+ REMOVE_TAG_TITLE: "Quitar",
425
+ NOTES_LABEL: "Descripci\xF3n / Notas (opcional):",
426
+ NOTES_PLACEHOLDER: "Qu\xE9 valida este test, condiciones previas, etc.",
427
+ TICKET_LABEL: "Ticket / Issue (opcional):",
428
+ TICKET_PLACEHOLDER: "Ej: PROJ-123, #42",
429
+ TICKET_WARN: "ID no v\xE1lido para el proveedor configurado (se guardar\xE1 igualmente)",
430
+ CONFIRM_DISCARD: "\xBFSeguro que quieres descartar el test grabado? Se perder\xE1n todos los pasos registrados.",
431
+ CONFIRM_DISCARD_BTN: "S\xED, descartar",
432
+ BACK_BTN: "Volver",
433
+ CONTINUE_RECORDING_BTN: "\u23FA Continuar grabando"
434
+ },
435
+ TEST_EDITOR: {
436
+ NO_TAGS: "Sin etiquetas",
437
+ SELECTED_SINGULAR: "seleccionado",
438
+ SELECTED_PLURAL: "seleccionados",
439
+ DESCRIBE_PLACEHOLDER: "Nombre del describe (opcional)",
440
+ COPY_DESCRIBE: "\u{1F5C2} Copiar describe()",
441
+ MULTI_SELECT: "\u{1F5C2} Multi-select",
442
+ CANCEL_SELECT: "\u2715 Cancelar",
443
+ COPY_CMDS_BTN: "\u{1F4CB} Copiar comandos",
444
+ COPY_ICPS_BTN: "\u{1F4CB} Copiar interceptores",
445
+ DEFAULT_DESCRIBE: "Suite de tests",
446
+ NO_TESTS: "No hay tests guardados",
447
+ DELETE_TITLE: "Eliminar",
448
+ GROUP_BY_TICKET: "\u{1F3AB} Agrupar por ticket",
449
+ UNGROUP_TICKET: "\u{1F3AB} Desagrupar",
450
+ NO_TICKET: "Sin ticket",
451
+ TICKET_LINK_TITLE: "Abrir ticket"
452
+ },
453
+ CONFIG: {
454
+ LANG_SECTION: "\u{1F310} Idioma",
455
+ LANG_FIELD: "Interfaz",
456
+ HTTP_SECTION: "\u26A1 HTTP Avanzado",
457
+ HTTP_TITLE: "Validaciones de body",
458
+ HTTP_SUB: "GET \u2192 response \xB7 POST/PUT \u2192 request",
459
+ FIXTURE_SECTION: "\u{1F9EA} Fixtures HTTP",
460
+ FIXTURE_TITLE: "Grabar respuestas como fixtures",
461
+ FIXTURE_SUB: "Las GET se guardan en cypress/fixtures y se stubean con cy.intercept({ fixture }).",
462
+ SELECTOR_SECTION: "\u{1F3AF} Estrategia de selector",
463
+ SELECTOR_LABEL: "Atributo preferido para cy.get()",
464
+ SELECTOR_OPT_DATACY: "data-cy (por defecto)",
465
+ SELECTOR_OPT_TESTID: "data-testid",
466
+ SELECTOR_OPT_ARIA: "aria-label",
467
+ SELECTOR_OPT_ID: "id (#elemento)",
468
+ SELECTOR_HINT: "El grabador buscar\xE1 este atributo primero. Si no existe, intentar\xE1 los dem\xE1s.",
469
+ FOLDER_SECTION: "\u{1F4C1} Carpeta Cypress",
470
+ FOLDER_CONNECTED: "conectado \u2014",
471
+ FOLDER_NOT_SET: "sin configurar",
472
+ FOLDER_CHANGE_BTN: "\u{1F4C1} Cambiar carpeta",
473
+ FOLDER_SELECT_BTN: "\u{1F4C1} Seleccionar carpeta",
474
+ FOLDER_REVOKE_BTN: "\u2715 Quitar acceso",
475
+ DATA_SECTION: "\u{1F4BE} Datos",
476
+ DATA_DESC: "Exporta todos tus tests a JSON o importa una copia de seguridad.",
477
+ EXPORT_BTN: "\u2B06\uFE0F Exportar tests",
478
+ EXPORT_DIALOG_TITLE: "\u2B06\uFE0F Exportar tests",
479
+ EXPORT_MODE_ALL: "Todo",
480
+ EXPORT_MODE_MANUAL: "Selecci\xF3n manual",
481
+ EXPORT_MODE_TAGS: "Por tags",
482
+ EXPORT_ALL_DESC: "Se exportar\xE1n todos los tests guardados.",
483
+ EXPORT_COUNT: "A exportar:",
484
+ EXPORT_CONFIRM: "\u2B06\uFE0F Exportar",
485
+ EXPORT_CANCEL: "Cancelar",
486
+ EXPORT_EMPTY: "No hay tests para exportar.",
487
+ EXPORT_NO_TAGS: "No hay tags disponibles.",
488
+ EXPORT_TAGS_HINT: "Selecciona uno o m\xE1s tags para ver qu\xE9 pruebas se exportar\xE1n.",
489
+ EXPORT_RESULT_LABEL: "Pruebas que se exportar\xE1n:",
490
+ IMPORT_BTN: "\u2B07\uFE0F Importar tests",
491
+ FOLDER_UPDATED_TOAST: "\u2713 Carpeta de Cypress actualizada",
492
+ FOLDER_ERROR_TOAST: "Error al acceder a la carpeta",
493
+ IMPORT_SUCCESS: "Datos importados correctamente.",
494
+ IMPORT_ERROR: "Error al importar.",
495
+ JSON_INVALID: "El archivo no es un JSON v\xE1lido.",
496
+ JSON_BAD_FORMAT: "El archivo no tiene el formato esperado.",
497
+ SMART_SELECTOR_SECTION: "\u{1F50D} Selector inteligente",
498
+ SMART_SELECTOR_TITLE: "Selector inteligente",
499
+ SMART_SELECTOR_SUB: "Muestra un picker al hacer click en elementos sin selector v\xE1lido.",
500
+ START_HIDDEN_SECTION: "\u{1F441} Visibilidad del widget",
501
+ START_HIDDEN_TITLE: "Iniciar oculto",
502
+ START_HIDDEN_SUB: "El widget arranca invisible. Usa Ctrl+Shift+E para mostrarlo u ocultarlo.",
503
+ RESUME_TTL_SECTION: "\u23F1 Continuidad de grabaci\xF3n",
504
+ RESUME_TTL_LABEL: "Reanudar sin preguntar (minutos)",
505
+ RESUME_TTL_HINT: "Si recargas o cambias de proyecto, una grabaci\xF3n activa se reanuda sin preguntar dentro de este margen. Pasado ese tiempo, te preguntar\xE1 si continuar o descartar.",
506
+ WIDGET_POSITION_SECTION: "\u{1F9F2} Posici\xF3n del widget",
507
+ WIDGET_POSITION_HINT: "Arrastra el bot\xF3n de grabar para moverlo donde no estorbe. Se recuerda su posici\xF3n.",
508
+ WIDGET_POSITION_RESET_BTN: "\u21BA Restablecer posici\xF3n",
509
+ WIDGET_POSITION_RESET_DONE: "\u2713 Posici\xF3n restablecida",
510
+ ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue tracker",
511
+ ISSUE_TRACKER_TITLE: "Vincular tests a tickets",
512
+ ISSUE_TRACKER_SUB: "A\xF1ade un ID de ticket al guardar y genera un enlace clickable en el listado.",
513
+ ISSUE_TRACKER_PROVIDER: "Proveedor",
514
+ ISSUE_TRACKER_BASE_URL: "URL base",
515
+ ISSUE_TRACKER_BASE_URL_PH: "Ej: https://miproyecto.atlassian.net",
516
+ LOGIN_SETUP_SECTION: "\u{1F510} Login setup",
517
+ LOGIN_SETUP_NOT_CONFIGURED: "No configurado",
518
+ LOGIN_SETUP_SET_UP_BTN: "Configurar",
519
+ LOGIN_SETUP_TITLE: "Configuraci\xF3n de login",
520
+ LOGIN_SETUP_CREATE_SCAFFOLD: "Crear scaffold",
521
+ LOGIN_SETUP_SELECT_EXISTING: "Seleccionar fichero existente",
522
+ LOGIN_SETUP_FILE_NAME_LABEL: "Nombre del fichero",
523
+ LOGIN_SETUP_FILE_NAME_PH: "Ej: cypress/common-services/login.service.ts",
524
+ LOGIN_SETUP_RESCAN: "\u{1F504} Re-escanear",
525
+ LOGIN_SETUP_FUNCTIONS_DETECTED: "Funciones detectadas",
526
+ LOGIN_SETUP_BLOCK_ASSIGN: "Asignaci\xF3n de bloques",
527
+ LOGIN_SETUP_NO_FUNCTIONS: "No se encontraron funciones exportadas. Rellena el scaffold y re-escanea.",
528
+ LOGIN_SETUP_BEFORE_LABEL: "Funci\xF3n before() (una vez por suite)",
529
+ LOGIN_SETUP_BEFORE_EACH_LABEL: "Funci\xF3n beforeEach() (antes de cada test)",
530
+ LOGIN_SETUP_NONE_OPTION: "\u2014 Ninguna \u2014",
531
+ LOGIN_SETUP_SUMMARY: "Fichero: {file} \xB7 before: {before} \xB7 beforeEach: {beforeEach}",
532
+ LOGIN_SETUP_SAVE_BTN: "\u{1F4BE} Guardar",
533
+ LOGIN_SETUP_CLEAR_BTN: "Eliminar configuraci\xF3n",
534
+ LOGIN_SETUP_CANCEL_BTN: "Cancelar",
535
+ LOGIN_SETUP_SOURCE_LABEL: "Origen del fichero de login",
536
+ LOGIN_SETUP_CREATE_SUB: "Genera un scaffold con funciones de ejemplo",
537
+ LOGIN_SETUP_SELECT_SUB: "Apunta a un servicio de login existente",
538
+ LOGIN_SETUP_INJECT_TITLE: "\xBFA\xF1adir bloques de login?",
539
+ LOGIN_SETUP_INJECT_TEXT: "Este fichero no tiene los bloques de login configurados. \xBFQuieres a\xF1adir el import y los bloques before/beforeEach ahora?",
540
+ LOGIN_SETUP_INJECT_CONFIRM: "S\xED, a\xF1adir"
541
+ },
542
+ SELECTOR_PICKER: {
543
+ TITLE: "Selecciona un elemento del DOM",
544
+ PREVIEW_LABEL: "navegar",
545
+ CONFIRM_HINT: "confirmar",
546
+ CANCEL_HINT: "cancelar",
547
+ QUALITY_EXCELLENT: "Excelente \u2014 tiene atributo de prueba (data-cy / data-testid / aria-label)",
548
+ QUALITY_GOOD: "Bueno \u2014 tiene un id v\xE1lido",
549
+ QUALITY_ACCEPTABLE: "Aceptable \u2014 solo tiene clases CSS",
550
+ QUALITY_POOR: "No recomendado \u2014 solo tag o estilo inline"
551
+ },
552
+ TEST_PREVISUALIZER: {
553
+ INTERCEPTORS: "Interceptores",
554
+ COPY_CMDS_BTN: "\u{1F4CB} Copiar comandos",
555
+ SHOW_INTERCEPTORS: "\u25BC Ver interceptores",
556
+ HIDE_INTERCEPTORS: "\u25B2 Ocultar interceptores",
557
+ SECTION_COMMANDS: "Comandos",
558
+ NO_CMDS_YET: "Sin comandos a\xFAn",
559
+ NO_ICP_SHORT: "Sin interceptores",
560
+ COPY_ICP_BTN: "\u{1F4CB} Copiar interceptores",
561
+ UP_TITLE: "Subir",
562
+ DOWN_TITLE: "Bajar",
563
+ DEL_TITLE: "Eliminar"
564
+ },
565
+ ADVANCED_EDITOR: {
566
+ REAUTH_BTN: "\u{1F513} Reactivar acceso",
567
+ PERMISSION_EXPIRED: "\u{1F511} El permiso ha caducado",
568
+ PERMISSION_EXPIRED_HINT: "Haz clic para reactivar el acceso a tu carpeta de Cypress.",
569
+ NO_ACCESS: "\u{1F512} Sin acceso a archivos locales",
570
+ NO_ACCESS_HINT: "Configura el acceso en \u2699\uFE0F Config.",
571
+ NO_FILES: "Sin archivos",
572
+ SELECT_FILE: "\u2190 Selecciona un archivo del \xE1rbol",
573
+ IT_LABEL: "\u{1F9EA} it() a insertar:",
574
+ COPY_IT_BTN: "\u{1F4CB} Copiar it()",
575
+ BEFORE_EACH_LABEL: "\u{1F500} beforeEach() interceptores:",
576
+ COPY_ICP_BTN: "\u{1F4CB} Copiar interceptores",
577
+ INSERT_BTN: "\u{1F4BE} Insertar en archivo",
578
+ EDIT_MANUAL_BTN: "\u270F\uFE0F Editar manualmente",
579
+ CLOSE_BTN: "\u2715 Cerrar",
580
+ NEW_FILE_BTN: "+ Nuevo archivo",
581
+ NEW_FOLDER_BTN: "+ Nueva carpeta",
582
+ REFRESH_BTN: "\u21BB Actualizar",
583
+ NEW_FILE_PLACEHOLDER: "nombre-del-test",
584
+ NEW_FOLDER_PLACEHOLDER: "nombre-de-carpeta",
585
+ NEW_FILE_CONFIRM: "Crear",
586
+ NEW_FILE_CANCEL: "Cancelar"
587
+ },
588
+ FILE_PREVIEW: {
589
+ NO_FILE: "Sin archivo",
590
+ COPY_TITLE: "Copiar contenido del editor",
591
+ BLOCK_IT: "\u{1F9EA} it()",
592
+ COPY_BTN: "\u{1F4CB} Copiar",
593
+ BLOCK_BEFORE_EACH: "\u{1F500} beforeEach()",
594
+ NO_CHANGES: "Sin cambios respecto al original",
595
+ NO_CHANGES_SHORT: "Sin cambios",
596
+ LAUNCH_BTN: "\u25B6 Lanzar test",
597
+ LAUNCH_LOCAL_ONLY: "Mu\xE9velo a local para poder probar",
598
+ LAUNCH_RUNNING: "\u23F3 Ejecutando\u2026",
599
+ LAUNCH_PASSED: "\u2713 Prueba superada",
600
+ LAUNCH_FAILED: "\u2717 Prueba fallida",
601
+ LAUNCH_NO_RUNNER: "No se detect\xF3 el runner local (\xBFlo has arrancado?)",
602
+ DIFF_BTN: "\u{1F4CA} Diff",
603
+ SAVE_BTN: "\u{1F4BE} Guardar",
604
+ CLOSE_BTN: "\u2715 Cerrar",
605
+ BACK_TO_EDITOR: "\u2190 Volver al editor",
606
+ INSERT_BTN: "\u{1FA84} Insertar bloques",
607
+ INSERT_TITLE: "Insertar it() y beforeEach() en el contenido del editor",
608
+ INSERT_DONE: "Bloques insertados en el editor",
609
+ INSERT_ERROR: "No se encontr\xF3 un bloque describe() v\xE1lido en el archivo"
610
+ },
611
+ RECORDER: {
612
+ FS_TITLE: "\u{1F4C1} Acceso a ficheros",
613
+ FS_LATER_BTN: "Ahora no",
614
+ FS_SELECT_BTN: "\u{1F4C1} Seleccionar carpeta",
615
+ FS_SUCCESS_TOAST: "\u2713 Carpeta de Cypress configurada",
616
+ FS_ERROR_TOAST: "Error al acceder a la carpeta",
617
+ 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.',
618
+ 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\xF3n espera esta estructura:',
619
+ FS_TREE_PICK_HINT: "\u2190 selecciona esta carpeta",
620
+ FS_TREE_READ_HINT: "\u2190 la extensi\xF3n leer\xE1 aqu\xED",
621
+ FS_PERMISSION_NOTE: "El permiso se guarda en el navegador y no se vuelve a solicitar.",
622
+ ASSERTION_SECTION: "\u2795 A\xF1adir aserci\xF3n",
623
+ ASSERT_SELECTOR_PH: 'selector, ej: [data-cy="btn"]',
624
+ ASSERT_VALUE_PH: "valor esperado",
625
+ ASSERT_ADD_BTN: "\u2795 A\xF1adir",
626
+ FILE_EDITOR_TITLE: "\u270F\uFE0F Editor de archivo",
627
+ FILE_SAVED_TOAST: "\u2713 Archivo guardado",
628
+ FILE_SAVE_ERROR_TOAST: "Error al guardar el archivo",
629
+ FIXTURES_WRITTEN_TOAST: "\u2713 Fixtures escritos en cypress/fixtures",
630
+ FIXTURES_NO_FOLDER_TOAST: "No se pudieron escribir los fixtures (configura la carpeta Cypress)",
631
+ FILE_UPLOAD_MANUAL_TOAST: "A\xF1ade {files} a cypress/fixtures/ antes de ejecutar el test.",
632
+ FILE_UPLOAD_COPIED_TOAST: "{files} copiado/s a cypress/fixtures/.",
633
+ FILE_UPLOAD_COPY_ERROR_TOAST: "No se pudo copiar {files} a cypress/fixtures/. A\xF1\xE1delo manualmente.",
634
+ BTN_CONFIG: "Config",
635
+ BTN_FILES: "Ficheros",
636
+ BTN_COMMANDS: "Comandos",
637
+ BTN_TESTS: "Tests",
638
+ PAUSE_TITLE: "Pausar (Ctrl+P)",
639
+ RESUME_TITLE: "Reanudar (Ctrl+P)",
640
+ BADGE_PAUSED: "\u23F8 PAUSA",
641
+ BADGE_REC: "\u25CF REC",
642
+ STOP_TITLE: "Detener (Ctrl+R)",
643
+ START_TITLE: "Grabar (Ctrl+R)",
644
+ SESSION_RESUME_TITLE: "\u23FA Grabaci\xF3n en curso",
645
+ SESSION_RESUME_TEXT: "Hay una grabaci\xF3n activa sin terminar.",
646
+ SESSION_RESUME_COUNT: "comandos capturados",
647
+ SESSION_CONTINUE_BTN: "Continuar grabando",
648
+ SESSION_DISCARD_BTN: "Descartar",
649
+ BTN_HELP: "Ayuda",
650
+ RECOVER_BTN: "Recuperar",
651
+ RECOVER_TITLE: "Recuperar la \xFAltima grabaci\xF3n detenida: {count} comandos ({time})",
652
+ RECOVER_TIME_NOW: "justo ahora",
653
+ RECOVER_TIME_MINUTES: "hace {m} min"
654
+ },
655
+ HELP: {
656
+ TITLE: "\u2753 Ayuda \u2014 Gu\xEDa r\xE1pida",
657
+ INTRO: "Todo lo que puede hacer el grabador.",
658
+ SEC_RECORDING: "\u23FA Grabar",
659
+ RECORDING_1: "Pulsa \u23FA (o Ctrl+R) para empezar; \u23F9 para parar y guardar.",
660
+ RECORDING_2: "Pausa / reanuda con \u23F8 (o Ctrl+P).",
661
+ SEC_SHORTCUTS: "\u2328\uFE0F Atajos de teclado",
662
+ SC_RECORD: "Ctrl+R \u2014 Grabar / detener",
663
+ SC_PAUSE: "Ctrl+P \u2014 Pausar / reanudar",
664
+ SC_TESTS: "Ctrl+1 \u2014 Panel de tests guardados",
665
+ SC_COMMANDS: "Ctrl+2 \u2014 Panel de comandos",
666
+ SC_CONFIG: "Ctrl+3 \u2014 Configuraci\xF3n",
667
+ SC_VISIBILITY: "Ctrl+Shift+E \u2014 Mostrar / ocultar el widget",
668
+ SC_HELP: "Ctrl+Shift+H \u2014 Esta ayuda",
669
+ SEC_CAPTURED: "\u{1F3AF} Qu\xE9 se graba",
670
+ CAP_CLICK: "Click \u2192 .click()",
671
+ CAP_DBLCLICK: "Doble-click \u2192 .dblclick()",
672
+ CAP_RIGHTCLICK: "Click derecho \u2192 .rightclick()",
673
+ CAP_TYPE: "Escribir en un campo \u2192 .clear().type(...)",
674
+ CAP_CHECK: "Checkbox / radio \u2192 .check() / .uncheck()",
675
+ CAP_SELECT: "<select> \u2192 .select(...)",
676
+ CAP_KEYS: 'Enter / Escape \u2192 .type("{enter}") / ("{esc}")',
677
+ CAP_ROUTE: "Cambio de ruta (SPA) \u2192 cy.url().should(...)",
678
+ CAP_HTTP: "fetch / XHR \u2192 cy.intercept + cy.wait",
679
+ SEC_ASSERT: "\u2705 Aserciones",
680
+ ASSERT_1: "Alt+click sobre un elemento para verificarlo sin ejecutar su acci\xF3n (texto, valor, checked o visible).",
681
+ ASSERT_2: "O usa el constructor de aserciones en el panel de Comandos.",
682
+ SEC_PANELS: "\u{1F5C2} Paneles",
683
+ PANEL_TESTS: "\u{1F4CB} Tests \u2014 guardados: filtrar por tag, copiar, combinar, exportar.",
684
+ PANEL_COMMANDS: "\u2328\uFE0F Comandos \u2014 de la grabaci\xF3n actual: reordenar, borrar, a\xF1adir aserciones.",
685
+ PANEL_CONFIG: "\u2699\uFE0F Config \u2014 idioma, selector, HTTP, carpeta Cypress, login setup, datos, visibilidad, posici\xF3n.",
686
+ PANEL_FILES: "\u{1F4C1} Ficheros \u2014 inserta tests en tus .cy.ts y lanza el runner.",
687
+ SEC_SELECTOR: "\u{1F50E} Selectores",
688
+ SELECTOR_1: "Elige el atributo preferido (data-cy, data-testid, aria-label, id) en Config.",
689
+ SELECTOR_2: "Si un click no tiene selector fiable, aparece un picker para elegir el mejor ancestro.",
690
+ SEC_DATA: "\u{1F4BE} Datos",
691
+ DATA_1: "Exporta tests a JSON (todo / selecci\xF3n / por tags).",
692
+ DATA_2: "Importa un JSON: se fusiona con lo existente (no se borra nada).",
693
+ SEC_ADVANCED: "\u{1F680} Avanzado",
694
+ ADV_INVISIBLE: "Modo invisible: start-hidden + Ctrl+Shift+E para grabar en producci\xF3n sin molestar.",
695
+ ADV_RUNNER: "Runner local: npx lib-e2e-cypress-runner para lanzar un spec headless desde el editor.",
696
+ ADV_CROSSAPP: "Cross-app: la grabaci\xF3n sobrevive al cambiar de micro-frontend (mismo origen).",
697
+ ADV_DRAG: "Arrastra el bot\xF3n \u23FA para mover el widget; recuerda su posici\xF3n.",
698
+ ADV_LOGIN: "Login Setup (Ctrl+3): apunta a tu servicio de login; el grabador inyecta before()/beforeEach() autom\xE1ticamente en cada test nuevo.",
699
+ CLOSE: "Cerrar",
700
+ TAB_REFERENCE: "Referencia r\xE1pida",
701
+ TAB_GUIDE: "Gu\xEDa de uso",
702
+ GUIDE_INTRO: "C\xF3mo sacarle partido al grabador, qu\xE9 cubre y qu\xE9 no.",
703
+ G_SEC_WORKFLOW: "\u{1F9ED} Flujo de trabajo",
704
+ G_WF_1: "1. Pulsa \u23FA (o Ctrl+R) para empezar a grabar.",
705
+ G_WF_2: "2. Usa tu app como un usuario: clicks, formularios, navegaci\xF3n. Cada acci\xF3n se convierte en un comando Cypress.",
706
+ G_WF_3: "3. A\xF1ade verificaciones con Alt+click sobre lo que quieras comprobar.",
707
+ G_WF_4: "4. Pulsa \u23F9 para parar; ponle nombre y tags, y gu\xE1rdalo.",
708
+ G_WF_5: "5. En \u{1F4C1} Ficheros, inserta el test en un .cy.ts o l\xE1nzalo con el runner local.",
709
+ G_SEC_COVERED: "\u2705 Qu\xE9 cubre",
710
+ G_COV_1: "Clicks, doble-click, click derecho, inputs de texto, checkbox/radio, select y teclas Enter/Escape.",
711
+ G_COV_2: "Navegaci\xF3n SPA (pushState/replaceState/popstate) \u2192 cy.url().should(...).",
712
+ G_COV_3: "Llamadas fetch/XHR (GET/POST/PUT) \u2192 cy.intercept + cy.wait, con validaci\xF3n de body opcional.",
713
+ G_COV_4: "Selector fiable (data-cy/testid/aria/id) y picker cuando no hay uno claro.",
714
+ G_COV_5: "Aserciones autom\xE1ticas (Alt+click) y constructor manual.",
715
+ G_COV_6: "Continuidad al cambiar de micro-frontend (mismo origen), modo invisible e i18n.",
716
+ G_COV_7: "Login Setup: configura tu funci\xF3n de login en Ctrl+3 \u2192 Login Setup y el grabador a\xF1ade los bloques before()/beforeEach() a cada test nuevo.",
717
+ G_SEC_NOTCOVERED: "\u{1F6AB} Qu\xE9 NO cubre (por ahora)",
718
+ G_NC_1: "Or\xEDgenes distintos / subdominios (solo mismo origen).",
719
+ G_NC_2: "Subida de ficheros (selectFile), arrastrar y soltar, y hover.",
720
+ G_NC_3: "La tecla Tab (Cypress no la soporta en .type()).",
721
+ G_NC_4: "Peticiones DELETE (se ignoran a prop\xF3sito).",
722
+ G_NC_5: "iframes y Shadow DOM de terceros pueden no capturarse."
723
+ }
724
+ };
725
+
726
+ // src/i18n/en.ts
727
+ var I18N_EN = {
728
+ MAIN_FRAME: {
729
+ SETTINGS: "Settings",
730
+ SHOW_ADVANCED_EDITOR: "Advanced editor",
731
+ DIALOG_SAVED_TESTS: "Saved tests",
732
+ DIALOG_COMMANDS: "Cypress commands previewer",
733
+ DIALOG_SAVE: "Save recording?"
734
+ },
735
+ SAVE_TEST: {
736
+ DESC_LABEL: "Test description",
737
+ CANCEL: "Cancel",
738
+ ASK: "Save the recorded test?",
739
+ YES_CONTINUE: "Yes, continue",
740
+ NO_DISCARD: "No, discard",
741
+ DESC_PLACEHOLDER: "E.g.: Successful login with valid credentials",
742
+ TAGS_LABEL: "Tags (optional, for later filtering):",
743
+ TAGS_PLACEHOLDER: "smoke, login, regression\u2026",
744
+ ADD_TAG: "+ Add",
745
+ NO_TAGS: "No tags",
746
+ SAVE_BTN: "\u{1F4BE} Save",
747
+ SAVE_AND_EDIT: "\u{1F4DD} Save and edit",
748
+ REMOVE_TAG_TITLE: "Remove",
749
+ NOTES_LABEL: "Description / Notes (optional):",
750
+ NOTES_PLACEHOLDER: "What this test validates, preconditions, etc.",
751
+ TICKET_LABEL: "Ticket / Issue (optional):",
752
+ TICKET_PLACEHOLDER: "E.g.: PROJ-123, #42",
753
+ TICKET_WARN: "Invalid ID for the configured provider (will be saved anyway)",
754
+ CONFIRM_DISCARD: "Are you sure you want to discard this recording? All recorded steps will be lost.",
755
+ CONFIRM_DISCARD_BTN: "Yes, discard",
756
+ BACK_BTN: "Go back",
757
+ CONTINUE_RECORDING_BTN: "\u23FA Continue recording"
758
+ },
759
+ TEST_EDITOR: {
760
+ NO_TAGS: "No tags",
761
+ SELECTED_SINGULAR: "selected",
762
+ SELECTED_PLURAL: "selected",
763
+ DESCRIBE_PLACEHOLDER: "describe name (optional)",
764
+ COPY_DESCRIBE: "\u{1F5C2} Copy describe()",
765
+ MULTI_SELECT: "\u{1F5C2} Multi-select",
766
+ CANCEL_SELECT: "\u2715 Cancel",
767
+ COPY_CMDS_BTN: "\u{1F4CB} Copy commands",
768
+ COPY_ICPS_BTN: "\u{1F4CB} Copy interceptors",
769
+ DEFAULT_DESCRIBE: "Test suite",
770
+ NO_TESTS: "No saved tests",
771
+ DELETE_TITLE: "Delete",
772
+ GROUP_BY_TICKET: "\u{1F3AB} Group by ticket",
773
+ UNGROUP_TICKET: "\u{1F3AB} Ungroup",
774
+ NO_TICKET: "No ticket",
775
+ TICKET_LINK_TITLE: "Open ticket"
776
+ },
777
+ CONFIG: {
778
+ LANG_SECTION: "\u{1F310} Language",
779
+ LANG_FIELD: "Interface",
780
+ HTTP_SECTION: "\u26A1 Advanced HTTP",
781
+ HTTP_TITLE: "Body validations",
782
+ HTTP_SUB: "GET \u2192 response \xB7 POST/PUT \u2192 request",
783
+ FIXTURE_SECTION: "\u{1F9EA} HTTP Fixtures",
784
+ FIXTURE_TITLE: "Record responses as fixtures",
785
+ FIXTURE_SUB: "GET responses are saved to cypress/fixtures and stubbed via cy.intercept({ fixture }).",
786
+ SELECTOR_SECTION: "\u{1F3AF} Selector strategy",
787
+ SELECTOR_LABEL: "Preferred attribute for cy.get()",
788
+ SELECTOR_OPT_DATACY: "data-cy (default)",
789
+ SELECTOR_OPT_TESTID: "data-testid",
790
+ SELECTOR_OPT_ARIA: "aria-label",
791
+ SELECTOR_OPT_ID: "id (#element)",
792
+ SELECTOR_HINT: "The recorder will look for this attribute first. If not found, it will try the others.",
793
+ FOLDER_SECTION: "\u{1F4C1} Cypress Folder",
794
+ FOLDER_CONNECTED: "connected \u2014",
795
+ FOLDER_NOT_SET: "not configured",
796
+ FOLDER_CHANGE_BTN: "\u{1F4C1} Change folder",
797
+ FOLDER_SELECT_BTN: "\u{1F4C1} Select folder",
798
+ FOLDER_REVOKE_BTN: "\u2715 Revoke access",
799
+ DATA_SECTION: "\u{1F4BE} Data",
800
+ DATA_DESC: "Export all your tests to JSON or import a backup.",
801
+ EXPORT_BTN: "\u2B06\uFE0F Export tests",
802
+ EXPORT_DIALOG_TITLE: "\u2B06\uFE0F Export tests",
803
+ EXPORT_MODE_ALL: "All",
804
+ EXPORT_MODE_MANUAL: "Manual selection",
805
+ EXPORT_MODE_TAGS: "By tags",
806
+ EXPORT_ALL_DESC: "All saved tests will be exported.",
807
+ EXPORT_COUNT: "To export:",
808
+ EXPORT_CONFIRM: "\u2B06\uFE0F Export",
809
+ EXPORT_CANCEL: "Cancel",
810
+ EXPORT_EMPTY: "No tests to export.",
811
+ EXPORT_NO_TAGS: "No tags available.",
812
+ EXPORT_TAGS_HINT: "Select one or more tags to preview which tests will be exported.",
813
+ EXPORT_RESULT_LABEL: "Tests that will be exported:",
814
+ IMPORT_BTN: "\u2B07\uFE0F Import tests",
815
+ FOLDER_UPDATED_TOAST: "\u2713 Cypress folder updated",
816
+ FOLDER_ERROR_TOAST: "Error accessing the folder",
817
+ IMPORT_SUCCESS: "Data imported successfully.",
818
+ IMPORT_ERROR: "Error importing.",
819
+ JSON_INVALID: "The file is not valid JSON.",
820
+ JSON_BAD_FORMAT: "The file does not have the expected format.",
821
+ SMART_SELECTOR_SECTION: "\u{1F50D} Smart selector",
822
+ SMART_SELECTOR_TITLE: "Smart selector",
823
+ SMART_SELECTOR_SUB: "Shows a picker when clicking elements with no valid selector.",
824
+ START_HIDDEN_SECTION: "\u{1F441} Widget visibility",
825
+ START_HIDDEN_TITLE: "Start hidden",
826
+ START_HIDDEN_SUB: "The widget starts invisible. Use Ctrl+Shift+E to show or hide it.",
827
+ RESUME_TTL_SECTION: "\u23F1 Recording continuity",
828
+ RESUME_TTL_LABEL: "Resume without asking (minutes)",
829
+ RESUME_TTL_HINT: "If you reload or switch projects, an active recording resumes without asking within this window. After that, you will be asked to continue or discard.",
830
+ WIDGET_POSITION_SECTION: "\u{1F9F2} Widget position",
831
+ WIDGET_POSITION_HINT: "Drag the record button to move it out of the way. Its position is remembered.",
832
+ WIDGET_POSITION_RESET_BTN: "\u21BA Reset position",
833
+ WIDGET_POSITION_RESET_DONE: "\u2713 Position reset",
834
+ ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue tracker",
835
+ ISSUE_TRACKER_TITLE: "Link tests to tickets",
836
+ ISSUE_TRACKER_SUB: "Add a ticket ID when saving and generate a clickable link in the test list.",
837
+ ISSUE_TRACKER_PROVIDER: "Provider",
838
+ ISSUE_TRACKER_BASE_URL: "Base URL",
839
+ ISSUE_TRACKER_BASE_URL_PH: "E.g.: https://myproject.atlassian.net",
840
+ LOGIN_SETUP_SECTION: "\u{1F510} Login setup",
841
+ LOGIN_SETUP_NOT_CONFIGURED: "Not configured",
842
+ LOGIN_SETUP_SET_UP_BTN: "Set up",
843
+ LOGIN_SETUP_TITLE: "Login setup",
844
+ LOGIN_SETUP_CREATE_SCAFFOLD: "Create scaffold",
845
+ LOGIN_SETUP_SELECT_EXISTING: "Select existing file",
846
+ LOGIN_SETUP_FILE_NAME_LABEL: "File name",
847
+ LOGIN_SETUP_FILE_NAME_PH: "E.g.: cypress/common-services/login.service.ts",
848
+ LOGIN_SETUP_RESCAN: "\u{1F504} Re-scan",
849
+ LOGIN_SETUP_FUNCTIONS_DETECTED: "Detected functions",
850
+ LOGIN_SETUP_BLOCK_ASSIGN: "Block assignment",
851
+ LOGIN_SETUP_NO_FUNCTIONS: "No exported functions found. Fill in the scaffold and re-scan.",
852
+ LOGIN_SETUP_BEFORE_LABEL: "before() function (once per suite)",
853
+ LOGIN_SETUP_BEFORE_EACH_LABEL: "beforeEach() function (before every test)",
854
+ LOGIN_SETUP_NONE_OPTION: "\u2014 None \u2014",
855
+ LOGIN_SETUP_SUMMARY: "File: {file} \xB7 before: {before} \xB7 beforeEach: {beforeEach}",
856
+ LOGIN_SETUP_SAVE_BTN: "\u{1F4BE} Save",
857
+ LOGIN_SETUP_CLEAR_BTN: "Remove configuration",
858
+ LOGIN_SETUP_CANCEL_BTN: "Cancel",
859
+ LOGIN_SETUP_SOURCE_LABEL: "Login file source",
860
+ LOGIN_SETUP_CREATE_SUB: "Generate a scaffold with sample functions",
861
+ LOGIN_SETUP_SELECT_SUB: "Point to an existing login service file",
862
+ LOGIN_SETUP_INJECT_TITLE: "Add login blocks?",
863
+ LOGIN_SETUP_INJECT_TEXT: "This file does not have the configured login blocks. Do you want to add the import and before/beforeEach blocks now?",
864
+ LOGIN_SETUP_INJECT_CONFIRM: "Yes, add them"
865
+ },
866
+ SELECTOR_PICKER: {
867
+ TITLE: "Select a DOM element",
868
+ PREVIEW_LABEL: "navigate",
869
+ CONFIRM_HINT: "confirm",
870
+ CANCEL_HINT: "cancel",
871
+ QUALITY_EXCELLENT: "Excellent \u2014 has a testing attribute (data-cy / data-testid / aria-label)",
872
+ QUALITY_GOOD: "Good \u2014 has a valid id",
873
+ QUALITY_ACCEPTABLE: "Acceptable \u2014 CSS classes only",
874
+ QUALITY_POOR: "Not recommended \u2014 tag name or inline style only"
875
+ },
876
+ TEST_PREVISUALIZER: {
877
+ INTERCEPTORS: "Interceptors",
878
+ COPY_CMDS_BTN: "\u{1F4CB} Copy commands",
879
+ SHOW_INTERCEPTORS: "\u25BC Show interceptors",
880
+ HIDE_INTERCEPTORS: "\u25B2 Hide interceptors",
881
+ SECTION_COMMANDS: "Commands",
882
+ NO_CMDS_YET: "No commands yet",
883
+ NO_ICP_SHORT: "No interceptors",
884
+ COPY_ICP_BTN: "\u{1F4CB} Copy interceptors",
885
+ UP_TITLE: "Move up",
886
+ DOWN_TITLE: "Move down",
887
+ DEL_TITLE: "Delete"
888
+ },
889
+ ADVANCED_EDITOR: {
890
+ REAUTH_BTN: "\u{1F513} Reactivate access",
891
+ PERMISSION_EXPIRED: "\u{1F511} Permission expired",
892
+ PERMISSION_EXPIRED_HINT: "Click to reactivate access to your Cypress folder.",
893
+ NO_ACCESS: "\u{1F512} No access to local files",
894
+ NO_ACCESS_HINT: "Configure access in \u2699\uFE0F Config.",
895
+ NO_FILES: "No files",
896
+ SELECT_FILE: "\u2190 Select a file from the tree",
897
+ IT_LABEL: "\u{1F9EA} it() to insert:",
898
+ COPY_IT_BTN: "\u{1F4CB} Copy it()",
899
+ BEFORE_EACH_LABEL: "\u{1F500} beforeEach() interceptors:",
900
+ COPY_ICP_BTN: "\u{1F4CB} Copy interceptors",
901
+ INSERT_BTN: "\u{1F4BE} Insert into file",
902
+ EDIT_MANUAL_BTN: "\u270F\uFE0F Edit manually",
903
+ CLOSE_BTN: "\u2715 Close",
904
+ NEW_FILE_BTN: "+ New file",
905
+ NEW_FOLDER_BTN: "+ New folder",
906
+ REFRESH_BTN: "\u21BB Refresh",
907
+ NEW_FILE_PLACEHOLDER: "test-name",
908
+ NEW_FOLDER_PLACEHOLDER: "folder-name",
909
+ NEW_FILE_CONFIRM: "Create",
910
+ NEW_FILE_CANCEL: "Cancel"
911
+ },
912
+ FILE_PREVIEW: {
913
+ NO_FILE: "No file",
914
+ COPY_TITLE: "Copy editor content",
915
+ BLOCK_IT: "\u{1F9EA} it()",
916
+ COPY_BTN: "\u{1F4CB} Copy",
917
+ BLOCK_BEFORE_EACH: "\u{1F500} beforeEach()",
918
+ NO_CHANGES: "No changes from original",
919
+ NO_CHANGES_SHORT: "No changes",
920
+ LAUNCH_BTN: "\u25B6 Run test",
921
+ LAUNCH_LOCAL_ONLY: "Move it to localhost to run tests",
922
+ LAUNCH_RUNNING: "\u23F3 Running\u2026",
923
+ LAUNCH_PASSED: "\u2713 Test passed",
924
+ LAUNCH_FAILED: "\u2717 Test failed",
925
+ LAUNCH_NO_RUNNER: "No local runner detected (did you start it?)",
926
+ DIFF_BTN: "\u{1F4CA} Diff",
927
+ SAVE_BTN: "\u{1F4BE} Save",
928
+ CLOSE_BTN: "\u2715 Close",
929
+ BACK_TO_EDITOR: "\u2190 Back to editor",
930
+ INSERT_BTN: "\u{1FA84} Insert blocks",
931
+ INSERT_TITLE: "Insert it() and beforeEach() into the editor content",
932
+ INSERT_DONE: "Blocks inserted into the editor",
933
+ INSERT_ERROR: "No valid describe() block found in the file"
934
+ },
935
+ RECORDER: {
936
+ FS_TITLE: "\u{1F4C1} File access",
937
+ FS_LATER_BTN: "Not now",
938
+ FS_SELECT_BTN: "\u{1F4C1} Select folder",
939
+ FS_SUCCESS_TOAST: "\u2713 Cypress folder configured",
940
+ FS_ERROR_TOAST: "Error accessing the folder",
941
+ 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.',
942
+ 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:',
943
+ FS_TREE_PICK_HINT: "\u2190 select this folder",
944
+ FS_TREE_READ_HINT: "\u2190 the extension will read here",
945
+ FS_PERMISSION_NOTE: "The permission is stored in the browser and will not be requested again.",
946
+ ASSERTION_SECTION: "\u2795 Add assertion",
947
+ ASSERT_SELECTOR_PH: 'selector, e.g.: [data-cy="btn"]',
948
+ ASSERT_VALUE_PH: "expected value",
949
+ ASSERT_ADD_BTN: "\u2795 Add",
950
+ FILE_EDITOR_TITLE: "\u270F\uFE0F File editor",
951
+ FILE_SAVED_TOAST: "\u2713 File saved",
952
+ FILE_SAVE_ERROR_TOAST: "Error saving the file",
953
+ FIXTURES_WRITTEN_TOAST: "\u2713 Fixtures written to cypress/fixtures",
954
+ FIXTURES_NO_FOLDER_TOAST: "Could not write fixtures (configure the Cypress folder)",
955
+ FILE_UPLOAD_MANUAL_TOAST: "Add {files} to cypress/fixtures/ before running the test.",
956
+ FILE_UPLOAD_COPIED_TOAST: "{files} copied to cypress/fixtures/.",
957
+ FILE_UPLOAD_COPY_ERROR_TOAST: "Could not copy {files} to cypress/fixtures/. Add it manually.",
958
+ BTN_CONFIG: "Config",
959
+ BTN_FILES: "Files",
960
+ BTN_COMMANDS: "Commands",
961
+ BTN_TESTS: "Tests",
962
+ PAUSE_TITLE: "Pause (Ctrl+P)",
963
+ RESUME_TITLE: "Resume (Ctrl+P)",
964
+ BADGE_PAUSED: "\u23F8 PAUSED",
965
+ BADGE_REC: "\u25CF REC",
966
+ STOP_TITLE: "Stop (Ctrl+R)",
967
+ START_TITLE: "Record (Ctrl+R)",
968
+ SESSION_RESUME_TITLE: "\u23FA Recording in progress",
969
+ SESSION_RESUME_TEXT: "There is an unfinished active recording.",
970
+ SESSION_RESUME_COUNT: "commands captured",
971
+ SESSION_CONTINUE_BTN: "Keep recording",
972
+ SESSION_DISCARD_BTN: "Discard",
973
+ BTN_HELP: "Help",
974
+ RECOVER_BTN: "Recover",
975
+ RECOVER_TITLE: "Recover the last stopped recording: {count} commands ({time})",
976
+ RECOVER_TIME_NOW: "just now",
977
+ RECOVER_TIME_MINUTES: "{m} min ago"
978
+ },
979
+ HELP: {
980
+ TITLE: "\u2753 Help \u2014 Quick guide",
981
+ INTRO: "Everything the recorder can do.",
982
+ SEC_RECORDING: "\u23FA Recording",
983
+ RECORDING_1: "Press \u23FA (or Ctrl+R) to start; \u23F9 to stop and save.",
984
+ RECORDING_2: "Pause / resume with \u23F8 (or Ctrl+P).",
985
+ SEC_SHORTCUTS: "\u2328\uFE0F Keyboard shortcuts",
986
+ SC_RECORD: "Ctrl+R \u2014 Record / stop",
987
+ SC_PAUSE: "Ctrl+P \u2014 Pause / resume",
988
+ SC_TESTS: "Ctrl+1 \u2014 Saved tests panel",
989
+ SC_COMMANDS: "Ctrl+2 \u2014 Commands panel",
990
+ SC_CONFIG: "Ctrl+3 \u2014 Settings",
991
+ SC_VISIBILITY: "Ctrl+Shift+E \u2014 Show / hide the widget",
992
+ SC_HELP: "Ctrl+Shift+H \u2014 This help",
993
+ SEC_CAPTURED: "\u{1F3AF} What gets recorded",
994
+ CAP_CLICK: "Click \u2192 .click()",
995
+ CAP_DBLCLICK: "Double-click \u2192 .dblclick()",
996
+ CAP_RIGHTCLICK: "Right-click \u2192 .rightclick()",
997
+ CAP_TYPE: "Type into a field \u2192 .clear().type(...)",
998
+ CAP_CHECK: "Checkbox / radio \u2192 .check() / .uncheck()",
999
+ CAP_SELECT: "<select> \u2192 .select(...)",
1000
+ CAP_KEYS: 'Enter / Escape \u2192 .type("{enter}") / ("{esc}")',
1001
+ CAP_ROUTE: "Route change (SPA) \u2192 cy.url().should(...)",
1002
+ CAP_HTTP: "fetch / XHR \u2192 cy.intercept + cy.wait",
1003
+ SEC_ASSERT: "\u2705 Assertions",
1004
+ ASSERT_1: "Alt+click an element to verify it without running its action (text, value, checked or visible).",
1005
+ ASSERT_2: "Or use the assertion builder in the Commands panel.",
1006
+ SEC_PANELS: "\u{1F5C2} Panels",
1007
+ PANEL_TESTS: "\u{1F4CB} Tests \u2014 saved tests: filter by tag, copy, combine, export.",
1008
+ PANEL_COMMANDS: "\u2328\uFE0F Commands \u2014 current recording: reorder, delete, add assertions.",
1009
+ PANEL_CONFIG: "\u2699\uFE0F Config \u2014 language, selector, HTTP, Cypress folder, login setup, data, visibility, position.",
1010
+ PANEL_FILES: "\u{1F4C1} Files \u2014 insert tests into your .cy.ts and launch the runner.",
1011
+ SEC_SELECTOR: "\u{1F50E} Selectors",
1012
+ SELECTOR_1: "Choose the preferred attribute (data-cy, data-testid, aria-label, id) in Config.",
1013
+ SELECTOR_2: "If a click has no reliable selector, a picker appears to choose the best ancestor.",
1014
+ SEC_DATA: "\u{1F4BE} Data",
1015
+ DATA_1: "Export tests to JSON (all / selection / by tags).",
1016
+ DATA_2: "Import a JSON: it merges into your data (nothing is wiped).",
1017
+ SEC_ADVANCED: "\u{1F680} Advanced",
1018
+ ADV_INVISIBLE: "Invisible mode: start-hidden + Ctrl+Shift+E to record in production unobtrusively.",
1019
+ ADV_RUNNER: "Local runner: npx lib-e2e-cypress-runner to run a spec headless from the editor.",
1020
+ ADV_CROSSAPP: "Cross-app: the recording survives switching micro-frontend (same origin).",
1021
+ ADV_DRAG: "Drag the \u23FA button to move the widget; its position is remembered.",
1022
+ ADV_LOGIN: "Login Setup (Ctrl+3): point to your login service; the recorder automatically injects before()/beforeEach() blocks into each new test.",
1023
+ CLOSE: "Close",
1024
+ TAB_REFERENCE: "Quick reference",
1025
+ TAB_GUIDE: "Usage guide",
1026
+ GUIDE_INTRO: "How to get the most out of the recorder, and what it does / doesn't cover.",
1027
+ G_SEC_WORKFLOW: "\u{1F9ED} Workflow",
1028
+ G_WF_1: "1. Press \u23FA (or Ctrl+R) to start recording.",
1029
+ G_WF_2: "2. Use your app like a user: clicks, forms, navigation. Each action becomes a Cypress command.",
1030
+ G_WF_3: "3. Add checks with Alt+click on whatever you want to verify.",
1031
+ G_WF_4: "4. Press \u23F9 to stop; give it a name and tags, and save it.",
1032
+ G_WF_5: "5. In \u{1F4C1} Files, insert the test into a .cy.ts or run it with the local runner.",
1033
+ G_SEC_COVERED: "\u2705 What it covers",
1034
+ G_COV_1: "Clicks, double-click, right-click, text inputs, checkbox/radio, select and Enter/Escape keys.",
1035
+ G_COV_2: "SPA navigation (pushState/replaceState/popstate) \u2192 cy.url().should(...).",
1036
+ G_COV_3: "fetch/XHR calls (GET/POST/PUT) \u2192 cy.intercept + cy.wait, with optional body validation.",
1037
+ G_COV_4: "Reliable selector (data-cy/testid/aria/id) and a picker when none is obvious.",
1038
+ G_COV_5: "Automatic assertions (Alt+click) and the manual builder.",
1039
+ G_COV_6: "Continuity when switching micro-frontend (same origin), invisible mode and i18n.",
1040
+ G_COV_7: "Login Setup: configure your login function under Ctrl+3 \u2192 Login Setup; the recorder adds before()/beforeEach() blocks to every new test.",
1041
+ G_SEC_NOTCOVERED: "\u{1F6AB} What it does NOT cover (yet)",
1042
+ G_NC_1: "Different origins / subdomains (same origin only).",
1043
+ G_NC_2: "File upload (selectFile), drag & drop, and hover.",
1044
+ G_NC_3: "The Tab key (Cypress can't .type() it).",
1045
+ G_NC_4: "DELETE requests (intentionally ignored).",
1046
+ G_NC_5: "Third-party iframes and Shadow DOM may not be captured."
1047
+ }
1048
+ };
1049
+
1050
+ // src/i18n/fr.ts
1051
+ var I18N_FR = {
1052
+ MAIN_FRAME: {
1053
+ SETTINGS: "Param\xE8tres",
1054
+ SHOW_ADVANCED_EDITOR: "\xC9diteur avanc\xE9",
1055
+ DIALOG_SAVED_TESTS: "Tests enregistr\xE9s",
1056
+ DIALOG_COMMANDS: "Aper\xE7u des commandes Cypress",
1057
+ DIALOG_SAVE: "Enregistrer l'enregistrement ?"
1058
+ },
1059
+ SAVE_TEST: {
1060
+ DESC_LABEL: "Description du test",
1061
+ CANCEL: "Annuler",
1062
+ ASK: "Enregistrer le test ?",
1063
+ YES_CONTINUE: "Oui, continuer",
1064
+ NO_DISCARD: "Non, ignorer",
1065
+ DESC_PLACEHOLDER: "Ex : Connexion r\xE9ussie avec identifiants valides",
1066
+ TAGS_LABEL: "\xC9tiquettes (optionnel, pour filtrer ensuite) :",
1067
+ TAGS_PLACEHOLDER: "smoke, login, r\xE9gression\u2026",
1068
+ ADD_TAG: "+ Ajouter",
1069
+ NO_TAGS: "Sans \xE9tiquettes",
1070
+ SAVE_BTN: "\u{1F4BE} Enregistrer",
1071
+ SAVE_AND_EDIT: "\u{1F4DD} Enregistrer et \xE9diter",
1072
+ REMOVE_TAG_TITLE: "Retirer",
1073
+ NOTES_LABEL: "Description / Notes (optionnel) :",
1074
+ NOTES_PLACEHOLDER: "Ce que ce test valide, conditions pr\xE9alables, etc.",
1075
+ TICKET_LABEL: "Ticket / Issue (optionnel) :",
1076
+ TICKET_PLACEHOLDER: "Ex : PROJ-123, #42",
1077
+ TICKET_WARN: "ID non valide pour le fournisseur configur\xE9 (sera enregistr\xE9 quand m\xEAme)",
1078
+ // TODO: translate
1079
+ CONFIRM_DISCARD: "\xCAtes-vous s\xFBr de vouloir abandonner cet enregistrement ? Toutes les \xE9tapes enregistr\xE9es seront perdues.",
1080
+ CONFIRM_DISCARD_BTN: "Oui, abandonner",
1081
+ BACK_BTN: "Retour",
1082
+ CONTINUE_RECORDING_BTN: "\u23FA Continuer l\u2019enregistrement"
1083
+ },
1084
+ TEST_EDITOR: {
1085
+ NO_TAGS: "Sans \xE9tiquettes",
1086
+ SELECTED_SINGULAR: "s\xE9lectionn\xE9",
1087
+ SELECTED_PLURAL: "s\xE9lectionn\xE9s",
1088
+ DESCRIBE_PLACEHOLDER: "Nom du describe (optionnel)",
1089
+ COPY_DESCRIBE: "\u{1F5C2} Copier describe()",
1090
+ MULTI_SELECT: "\u{1F5C2} Multi-s\xE9lection",
1091
+ CANCEL_SELECT: "\u2715 Annuler",
1092
+ COPY_CMDS_BTN: "\u{1F4CB} Copier les commandes",
1093
+ COPY_ICPS_BTN: "\u{1F4CB} Copier les intercepteurs",
1094
+ DEFAULT_DESCRIBE: "Suite de tests",
1095
+ NO_TESTS: "Aucun test enregistr\xE9",
1096
+ DELETE_TITLE: "Supprimer",
1097
+ GROUP_BY_TICKET: "\u{1F3AB} Grouper par ticket",
1098
+ UNGROUP_TICKET: "\u{1F3AB} D\xE9grouper",
1099
+ NO_TICKET: "Sans ticket",
1100
+ TICKET_LINK_TITLE: "Ouvrir le ticket"
1101
+ },
1102
+ CONFIG: {
1103
+ LANG_SECTION: "\u{1F310} Langue",
1104
+ LANG_FIELD: "Interface",
1105
+ HTTP_SECTION: "\u26A1 HTTP Avanc\xE9",
1106
+ HTTP_TITLE: "Validations du corps",
1107
+ HTTP_SUB: "GET \u2192 r\xE9ponse \xB7 POST/PUT \u2192 requ\xEAte",
1108
+ FIXTURE_SECTION: "\u{1F9EA} Fixtures HTTP",
1109
+ FIXTURE_TITLE: "Enregistrer les r\xE9ponses comme fixtures",
1110
+ FIXTURE_SUB: "Les GET sont enregistr\xE9es dans cypress/fixtures et stub\xE9es via cy.intercept({ fixture }).",
1111
+ SELECTOR_SECTION: "\u{1F3AF} Strat\xE9gie de s\xE9lecteur",
1112
+ SELECTOR_LABEL: "Attribut pr\xE9f\xE9r\xE9 pour cy.get()",
1113
+ SELECTOR_OPT_DATACY: "data-cy (par d\xE9faut)",
1114
+ SELECTOR_OPT_TESTID: "data-testid",
1115
+ SELECTOR_OPT_ARIA: "aria-label",
1116
+ SELECTOR_OPT_ID: "id (#\xE9l\xE9ment)",
1117
+ SELECTOR_HINT: "L'enregistreur cherchera d'abord cet attribut. Si absent, il essaiera les autres.",
1118
+ FOLDER_SECTION: "\u{1F4C1} Dossier Cypress",
1119
+ FOLDER_CONNECTED: "connect\xE9 \u2014",
1120
+ FOLDER_NOT_SET: "non configur\xE9",
1121
+ FOLDER_CHANGE_BTN: "\u{1F4C1} Changer de dossier",
1122
+ FOLDER_SELECT_BTN: "\u{1F4C1} S\xE9lectionner un dossier",
1123
+ FOLDER_REVOKE_BTN: "\u2715 R\xE9voquer l'acc\xE8s",
1124
+ DATA_SECTION: "\u{1F4BE} Donn\xE9es",
1125
+ DATA_DESC: "Exportez tous vos tests en JSON ou importez une sauvegarde.",
1126
+ EXPORT_BTN: "\u2B06\uFE0F Exporter les tests",
1127
+ EXPORT_DIALOG_TITLE: "\u2B06\uFE0F Exporter les tests",
1128
+ EXPORT_MODE_ALL: "Tout",
1129
+ EXPORT_MODE_MANUAL: "S\xE9lection manuelle",
1130
+ EXPORT_MODE_TAGS: "Par tags",
1131
+ EXPORT_ALL_DESC: "Tous les tests enregistr\xE9s seront export\xE9s.",
1132
+ EXPORT_COUNT: "\xC0 exporter :",
1133
+ EXPORT_CONFIRM: "\u2B06\uFE0F Exporter",
1134
+ EXPORT_CANCEL: "Annuler",
1135
+ EXPORT_EMPTY: "Aucun test \xE0 exporter.",
1136
+ EXPORT_NO_TAGS: "Aucun tag disponible.",
1137
+ EXPORT_TAGS_HINT: "S\xE9lectionnez un ou plusieurs tags pour voir les tests qui seront export\xE9s.",
1138
+ EXPORT_RESULT_LABEL: "Tests qui seront export\xE9s :",
1139
+ IMPORT_BTN: "\u2B07\uFE0F Importer les tests",
1140
+ FOLDER_UPDATED_TOAST: "\u2713 Dossier Cypress mis \xE0 jour",
1141
+ FOLDER_ERROR_TOAST: "Erreur lors de l'acc\xE8s au dossier",
1142
+ IMPORT_SUCCESS: "Donn\xE9es import\xE9es avec succ\xE8s.",
1143
+ IMPORT_ERROR: "Erreur lors de l'importation.",
1144
+ JSON_INVALID: "Le fichier n'est pas un JSON valide.",
1145
+ JSON_BAD_FORMAT: "Le fichier n'a pas le format attendu.",
1146
+ SMART_SELECTOR_SECTION: "\u{1F50D} S\xE9lecteur intelligent",
1147
+ SMART_SELECTOR_TITLE: "S\xE9lecteur intelligent",
1148
+ SMART_SELECTOR_SUB: "Affiche un s\xE9lecteur lors du clic sur des \xE9l\xE9ments sans s\xE9lecteur valide.",
1149
+ START_HIDDEN_SECTION: "\u{1F441} Visibilit\xE9 du widget",
1150
+ START_HIDDEN_TITLE: "D\xE9marrer masqu\xE9",
1151
+ START_HIDDEN_SUB: "Le widget d\xE9marre invisible. Utilisez Ctrl+Shift+E pour l'afficher ou le masquer.",
1152
+ RESUME_TTL_SECTION: "\u23F1 Continuit\xE9 d'enregistrement",
1153
+ RESUME_TTL_LABEL: "Reprendre sans demander (minutes)",
1154
+ RESUME_TTL_HINT: "Si vous rechargez ou changez de projet, un enregistrement actif reprend sans demander dans ce d\xE9lai. Au-del\xE0, il vous demandera de continuer ou d'ignorer.",
1155
+ WIDGET_POSITION_SECTION: "\u{1F9F2} Position du widget",
1156
+ WIDGET_POSITION_HINT: "Fais glisser le bouton d'enregistrement pour le d\xE9placer. Sa position est m\xE9moris\xE9e.",
1157
+ WIDGET_POSITION_RESET_BTN: "\u21BA R\xE9initialiser la position",
1158
+ WIDGET_POSITION_RESET_DONE: "\u2713 Position r\xE9initialis\xE9e",
1159
+ ISSUE_TRACKER_SECTION: "\u{1F3AB} Gestionnaire de tickets",
1160
+ ISSUE_TRACKER_TITLE: "Lier les tests aux tickets",
1161
+ ISSUE_TRACKER_SUB: "Ajoutez un ID de ticket lors de l'enregistrement et g\xE9n\xE9rez un lien cliquable.",
1162
+ ISSUE_TRACKER_PROVIDER: "Fournisseur",
1163
+ ISSUE_TRACKER_BASE_URL: "URL de base",
1164
+ ISSUE_TRACKER_BASE_URL_PH: "Ex : https://monprojet.atlassian.net",
1165
+ LOGIN_SETUP_SECTION: "\u{1F510} Login setup",
1166
+ LOGIN_SETUP_NOT_CONFIGURED: "Non configur\xE9",
1167
+ LOGIN_SETUP_SET_UP_BTN: "Configurer",
1168
+ LOGIN_SETUP_TITLE: "Configuration du login",
1169
+ LOGIN_SETUP_CREATE_SCAFFOLD: "Cr\xE9er un scaffold",
1170
+ LOGIN_SETUP_SELECT_EXISTING: "S\xE9lectionner un fichier existant",
1171
+ LOGIN_SETUP_FILE_NAME_LABEL: "Nom du fichier",
1172
+ LOGIN_SETUP_FILE_NAME_PH: "Ex : cypress/common-services/login.service.ts",
1173
+ LOGIN_SETUP_RESCAN: "\u{1F504} Re-scanner",
1174
+ LOGIN_SETUP_FUNCTIONS_DETECTED: "Fonctions d\xE9tect\xE9es",
1175
+ LOGIN_SETUP_BLOCK_ASSIGN: "Affectation des blocs",
1176
+ LOGIN_SETUP_NO_FUNCTIONS: "Aucune fonction export\xE9e trouv\xE9e. Remplissez le scaffold et re-scannez.",
1177
+ LOGIN_SETUP_BEFORE_LABEL: "Fonction before() (une fois par suite)",
1178
+ LOGIN_SETUP_BEFORE_EACH_LABEL: "Fonction beforeEach() (avant chaque test)",
1179
+ LOGIN_SETUP_NONE_OPTION: "\u2014 Aucune \u2014",
1180
+ LOGIN_SETUP_SUMMARY: "Fichier : {file} \xB7 before : {before} \xB7 beforeEach : {beforeEach}",
1181
+ LOGIN_SETUP_SAVE_BTN: "\u{1F4BE} Enregistrer",
1182
+ LOGIN_SETUP_CLEAR_BTN: "Supprimer la configuration",
1183
+ LOGIN_SETUP_CANCEL_BTN: "Annuler",
1184
+ LOGIN_SETUP_SOURCE_LABEL: "Source du fichier de login",
1185
+ LOGIN_SETUP_CREATE_SUB: "G\xE9n\xE9rer un scaffold avec des fonctions exemples",
1186
+ LOGIN_SETUP_SELECT_SUB: "Pointer vers un fichier de service de login existant",
1187
+ LOGIN_SETUP_INJECT_TITLE: "Ajouter les blocs de login ?",
1188
+ LOGIN_SETUP_INJECT_TEXT: "Ce fichier ne contient pas les blocs de login configur\xE9s. Voulez-vous ajouter l'import et les blocs before/beforeEach maintenant ?",
1189
+ LOGIN_SETUP_INJECT_CONFIRM: "Oui, ajouter"
1190
+ },
1191
+ SELECTOR_PICKER: {
1192
+ TITLE: "S\xE9lectionnez un \xE9l\xE9ment du DOM",
1193
+ PREVIEW_LABEL: "naviguer",
1194
+ CONFIRM_HINT: "confirmer",
1195
+ CANCEL_HINT: "annuler",
1196
+ QUALITY_EXCELLENT: "Excellent \u2014 attribut de test pr\xE9sent (data-cy / data-testid / aria-label)",
1197
+ QUALITY_GOOD: "Bon \u2014 id valide",
1198
+ QUALITY_ACCEPTABLE: "Acceptable \u2014 classes CSS uniquement",
1199
+ QUALITY_POOR: "D\xE9conseill\xE9 \u2014 seulement le nom de balise ou style inline"
1200
+ },
1201
+ TEST_PREVISUALIZER: {
1202
+ INTERCEPTORS: "Intercepteurs",
1203
+ COPY_CMDS_BTN: "\u{1F4CB} Copier les commandes",
1204
+ SHOW_INTERCEPTORS: "\u25BC Voir les intercepteurs",
1205
+ HIDE_INTERCEPTORS: "\u25B2 Masquer les intercepteurs",
1206
+ SECTION_COMMANDS: "Commandes",
1207
+ NO_CMDS_YET: "Aucune commande encore",
1208
+ NO_ICP_SHORT: "Aucun intercepteur",
1209
+ COPY_ICP_BTN: "\u{1F4CB} Copier les intercepteurs",
1210
+ UP_TITLE: "Monter",
1211
+ DOWN_TITLE: "Descendre",
1212
+ DEL_TITLE: "Supprimer"
1213
+ },
1214
+ ADVANCED_EDITOR: {
1215
+ REAUTH_BTN: "\u{1F513} R\xE9activer l'acc\xE8s",
1216
+ PERMISSION_EXPIRED: "\u{1F511} Autorisation expir\xE9e",
1217
+ PERMISSION_EXPIRED_HINT: "Cliquez pour r\xE9activer l'acc\xE8s \xE0 votre dossier Cypress.",
1218
+ NO_ACCESS: "\u{1F512} Pas d'acc\xE8s aux fichiers locaux",
1219
+ NO_ACCESS_HINT: "Configurez l'acc\xE8s dans \u2699\uFE0F Config.",
1220
+ NO_FILES: "Aucun fichier",
1221
+ SELECT_FILE: "\u2190 S\xE9lectionnez un fichier dans l'arborescence",
1222
+ IT_LABEL: "\u{1F9EA} it() \xE0 ins\xE9rer :",
1223
+ COPY_IT_BTN: "\u{1F4CB} Copier it()",
1224
+ BEFORE_EACH_LABEL: "\u{1F500} beforeEach() intercepteurs :",
1225
+ COPY_ICP_BTN: "\u{1F4CB} Copier les intercepteurs",
1226
+ INSERT_BTN: "\u{1F4BE} Ins\xE9rer dans le fichier",
1227
+ EDIT_MANUAL_BTN: "\u270F\uFE0F \xC9diter manuellement",
1228
+ CLOSE_BTN: "\u2715 Fermer",
1229
+ NEW_FILE_BTN: "+ Nouveau fichier",
1230
+ NEW_FOLDER_BTN: "+ Nouveau dossier",
1231
+ REFRESH_BTN: "\u21BB Actualiser",
1232
+ NEW_FILE_PLACEHOLDER: "nom-du-test",
1233
+ NEW_FOLDER_PLACEHOLDER: "nom-du-dossier",
1234
+ NEW_FILE_CONFIRM: "Cr\xE9er",
1235
+ NEW_FILE_CANCEL: "Annuler"
1236
+ },
1237
+ FILE_PREVIEW: {
1238
+ NO_FILE: "Sans fichier",
1239
+ COPY_TITLE: "Copier le contenu de l'\xE9diteur",
1240
+ BLOCK_IT: "\u{1F9EA} it()",
1241
+ COPY_BTN: "\u{1F4CB} Copier",
1242
+ BLOCK_BEFORE_EACH: "\u{1F500} beforeEach()",
1243
+ NO_CHANGES: "Aucun changement par rapport \xE0 l'original",
1244
+ NO_CHANGES_SHORT: "Aucun changement",
1245
+ LAUNCH_BTN: "\u25B6 Lancer le test",
1246
+ LAUNCH_LOCAL_ONLY: "Passe en local pour pouvoir tester",
1247
+ LAUNCH_RUNNING: "\u23F3 Ex\xE9cution\u2026",
1248
+ LAUNCH_PASSED: "\u2713 Test r\xE9ussi",
1249
+ LAUNCH_FAILED: "\u2717 Test \xE9chou\xE9",
1250
+ LAUNCH_NO_RUNNER: "Aucun runner local d\xE9tect\xE9 (l'avez-vous d\xE9marr\xE9 ?)",
1251
+ DIFF_BTN: "\u{1F4CA} Diff",
1252
+ SAVE_BTN: "\u{1F4BE} Enregistrer",
1253
+ CLOSE_BTN: "\u2715 Fermer",
1254
+ BACK_TO_EDITOR: "\u2190 Retour \xE0 l'\xE9diteur",
1255
+ INSERT_BTN: "\u{1FA84} Ins\xE9rer les blocs",
1256
+ INSERT_TITLE: "Ins\xE9rer it() et beforeEach() dans le contenu de l'\xE9diteur",
1257
+ INSERT_DONE: "Blocs ins\xE9r\xE9s dans l'\xE9diteur",
1258
+ INSERT_ERROR: "Aucun bloc describe() valide trouv\xE9 dans le fichier"
1259
+ },
1260
+ RECORDER: {
1261
+ FS_TITLE: "\u{1F4C1} Acc\xE8s aux fichiers",
1262
+ FS_LATER_BTN: "Pas maintenant",
1263
+ FS_SELECT_BTN: "\u{1F4C1} S\xE9lectionner un dossier",
1264
+ FS_SUCCESS_TOAST: "\u2713 Dossier Cypress configur\xE9",
1265
+ FS_ERROR_TOAST: "Erreur lors de l'acc\xE8s au dossier",
1266
+ FS_INTRO_HTML: `L'<strong style="color:#e6edf3">\xE9diteur avanc\xE9</strong> peut ins\xE9rer 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.`,
1267
+ FS_STRUCTURE_HINT_HTML: `S\xE9lectionnez 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 :`,
1268
+ FS_TREE_PICK_HINT: "\u2190 s\xE9lectionnez ce dossier",
1269
+ FS_TREE_READ_HINT: "\u2190 l'extension lira ici",
1270
+ FS_PERMISSION_NOTE: "L'autorisation est enregistr\xE9e dans le navigateur et ne sera plus demand\xE9e.",
1271
+ ASSERTION_SECTION: "\u2795 Ajouter une assertion",
1272
+ ASSERT_SELECTOR_PH: 's\xE9lecteur, ex : [data-cy="btn"]',
1273
+ ASSERT_VALUE_PH: "valeur attendue",
1274
+ ASSERT_ADD_BTN: "\u2795 Ajouter",
1275
+ FILE_EDITOR_TITLE: "\u270F\uFE0F \xC9diteur de fichier",
1276
+ FILE_SAVED_TOAST: "\u2713 Fichier enregistr\xE9",
1277
+ FILE_SAVE_ERROR_TOAST: "Erreur lors de l'enregistrement",
1278
+ FIXTURES_WRITTEN_TOAST: "\u2713 Fixtures \xE9crites dans cypress/fixtures",
1279
+ FIXTURES_NO_FOLDER_TOAST: "Impossible d'\xE9crire les fixtures (configure le dossier Cypress)",
1280
+ FILE_UPLOAD_MANUAL_TOAST: "Ajoutez {files} \xE0 cypress/fixtures/ avant d'ex\xE9cuter le test.",
1281
+ // TODO: translate
1282
+ FILE_UPLOAD_COPIED_TOAST: "{files} copi\xE9(s) dans cypress/fixtures/.",
1283
+ // TODO: translate
1284
+ FILE_UPLOAD_COPY_ERROR_TOAST: "Impossible de copier {files} vers cypress/fixtures/. Ajoutez-le manuellement.",
1285
+ // TODO: translate
1286
+ BTN_CONFIG: "Config",
1287
+ BTN_FILES: "Fichiers",
1288
+ BTN_COMMANDS: "Commandes",
1289
+ BTN_TESTS: "Tests",
1290
+ PAUSE_TITLE: "Pause (Ctrl+P)",
1291
+ RESUME_TITLE: "Reprendre (Ctrl+P)",
1292
+ BADGE_PAUSED: "\u23F8 PAUSE",
1293
+ BADGE_REC: "\u25CF REC",
1294
+ STOP_TITLE: "Arr\xEAter (Ctrl+R)",
1295
+ START_TITLE: "Enregistrer (Ctrl+R)",
1296
+ SESSION_RESUME_TITLE: "\u23FA Enregistrement en cours",
1297
+ SESSION_RESUME_TEXT: "Un enregistrement actif est inachev\xE9.",
1298
+ SESSION_RESUME_COUNT: "commandes captur\xE9es",
1299
+ SESSION_CONTINUE_BTN: "Continuer l'enregistrement",
1300
+ SESSION_DISCARD_BTN: "Ignorer",
1301
+ BTN_HELP: "Aide",
1302
+ RECOVER_BTN: "R\xE9cup\xE9rer",
1303
+ RECOVER_TITLE: "R\xE9cup\xE9rer le dernier enregistrement arr\xEAt\xE9 : {count} commandes ({time})",
1304
+ RECOVER_TIME_NOW: "\xE0 l\u2019instant",
1305
+ RECOVER_TIME_MINUTES: "il y a {m} min"
1306
+ },
1307
+ HELP: {
1308
+ TITLE: "\u2753 Aide \u2014 Guide rapide",
1309
+ INTRO: "Tout ce que l'enregistreur sait faire.",
1310
+ SEC_RECORDING: "\u23FA Enregistrer",
1311
+ RECORDING_1: "Appuie sur \u23FA (ou Ctrl+R) pour commencer ; \u23F9 pour arr\xEAter et enregistrer.",
1312
+ RECORDING_2: "Pause / reprise avec \u23F8 (ou Ctrl+P).",
1313
+ SEC_SHORTCUTS: "\u2328\uFE0F Raccourcis clavier",
1314
+ SC_RECORD: "Ctrl+R \u2014 Enregistrer / arr\xEAter",
1315
+ SC_PAUSE: "Ctrl+P \u2014 Pause / reprise",
1316
+ SC_TESTS: "Ctrl+1 \u2014 Panneau des tests enregistr\xE9s",
1317
+ SC_COMMANDS: "Ctrl+2 \u2014 Panneau des commandes",
1318
+ SC_CONFIG: "Ctrl+3 \u2014 Param\xE8tres",
1319
+ SC_VISIBILITY: "Ctrl+Shift+E \u2014 Afficher / masquer le widget",
1320
+ SC_HELP: "Ctrl+Shift+H \u2014 Cette aide",
1321
+ SEC_CAPTURED: "\u{1F3AF} Ce qui est enregistr\xE9",
1322
+ CAP_CLICK: "Clic \u2192 .click()",
1323
+ CAP_DBLCLICK: "Double-clic \u2192 .dblclick()",
1324
+ CAP_RIGHTCLICK: "Clic droit \u2192 .rightclick()",
1325
+ CAP_TYPE: "Saisie dans un champ \u2192 .clear().type(...)",
1326
+ CAP_CHECK: "Case \xE0 cocher / radio \u2192 .check() / .uncheck()",
1327
+ CAP_SELECT: "<select> \u2192 .select(...)",
1328
+ CAP_KEYS: 'Entr\xE9e / \xC9chap \u2192 .type("{enter}") / ("{esc}")',
1329
+ CAP_ROUTE: "Changement de route (SPA) \u2192 cy.url().should(...)",
1330
+ CAP_HTTP: "fetch / XHR \u2192 cy.intercept + cy.wait",
1331
+ SEC_ASSERT: "\u2705 Assertions",
1332
+ ASSERT_1: "Alt+clic sur un \xE9l\xE9ment pour le v\xE9rifier sans ex\xE9cuter son action (texte, valeur, coch\xE9 ou visible).",
1333
+ ASSERT_2: "Ou utilise le constructeur d'assertions dans le panneau Commandes.",
1334
+ SEC_PANELS: "\u{1F5C2} Panneaux",
1335
+ PANEL_TESTS: "\u{1F4CB} Tests \u2014 enregistr\xE9s : filtrer par tag, copier, combiner, exporter.",
1336
+ PANEL_COMMANDS: "\u2328\uFE0F Commandes \u2014 enregistrement en cours : r\xE9ordonner, supprimer, ajouter des assertions.",
1337
+ PANEL_CONFIG: "\u2699\uFE0F Config \u2014 langue, s\xE9lecteur, HTTP, dossier Cypress, login setup, donn\xE9es, visibilit\xE9, position.",
1338
+ PANEL_FILES: "\u{1F4C1} Fichiers \u2014 ins\xE8re des tests dans tes .cy.ts et lance le runner.",
1339
+ SEC_SELECTOR: "\u{1F50E} S\xE9lecteurs",
1340
+ SELECTOR_1: "Choisis l'attribut pr\xE9f\xE9r\xE9 (data-cy, data-testid, aria-label, id) dans Config.",
1341
+ SELECTOR_2: "Si un clic n'a pas de s\xE9lecteur fiable, un s\xE9lecteur appara\xEEt pour choisir le meilleur anc\xEAtre.",
1342
+ SEC_DATA: "\u{1F4BE} Donn\xE9es",
1343
+ DATA_1: "Exporte les tests en JSON (tout / s\xE9lection / par tags).",
1344
+ DATA_2: "Importe un JSON : il fusionne avec tes donn\xE9es (rien n'est effac\xE9).",
1345
+ SEC_ADVANCED: "\u{1F680} Avanc\xE9",
1346
+ ADV_INVISIBLE: "Mode invisible : start-hidden + Ctrl+Shift+E pour enregistrer en production discr\xE8tement.",
1347
+ ADV_RUNNER: "Runner local : npx lib-e2e-cypress-runner pour lancer un spec headless depuis l'\xE9diteur.",
1348
+ ADV_CROSSAPP: "Cross-app : l'enregistrement survit au changement de micro-frontend (m\xEAme origine).",
1349
+ ADV_DRAG: "Fais glisser le bouton \u23FA pour d\xE9placer le widget ; sa position est m\xE9moris\xE9e.",
1350
+ ADV_LOGIN: "Login Setup (Ctrl+3): apunta a tu servicio de login; el grabador inyecta before()/beforeEach() autom\xE1ticamente en cada test nuevo.",
1351
+ // TODO: translate (fr)
1352
+ CLOSE: "Fermer",
1353
+ TAB_REFERENCE: "R\xE9f\xE9rence rapide",
1354
+ TAB_GUIDE: "Guide d'utilisation",
1355
+ // TODO: translate (fr) — usage guide body kept in Spanish for now.
1356
+ GUIDE_INTRO: "C\xF3mo sacarle partido al grabador, qu\xE9 cubre y qu\xE9 no.",
1357
+ G_SEC_WORKFLOW: "\u{1F9ED} Flujo de trabajo",
1358
+ G_WF_1: "1. Pulsa \u23FA (o Ctrl+R) para empezar a grabar.",
1359
+ G_WF_2: "2. Usa tu app como un usuario: clicks, formularios, navegaci\xF3n. Cada acci\xF3n se convierte en un comando Cypress.",
1360
+ G_WF_3: "3. A\xF1ade verificaciones con Alt+click sobre lo que quieras comprobar.",
1361
+ G_WF_4: "4. Pulsa \u23F9 para parar; ponle nombre y tags, y gu\xE1rdalo.",
1362
+ G_WF_5: "5. En \u{1F4C1} Ficheros, inserta el test en un .cy.ts o l\xE1nzalo con el runner local.",
1363
+ G_SEC_COVERED: "\u2705 Qu\xE9 cubre",
1364
+ G_COV_1: "Clicks, doble-click, click derecho, inputs de texto, checkbox/radio, select y teclas Enter/Escape.",
1365
+ G_COV_2: "Navegaci\xF3n SPA (pushState/replaceState/popstate) \u2192 cy.url().should(...).",
1366
+ G_COV_3: "Llamadas fetch/XHR (GET/POST/PUT) \u2192 cy.intercept + cy.wait, con validaci\xF3n de body opcional.",
1367
+ G_COV_4: "Selector fiable (data-cy/testid/aria/id) y picker cuando no hay uno claro.",
1368
+ G_COV_5: "Aserciones autom\xE1ticas (Alt+click) y constructor manual.",
1369
+ G_COV_6: "Continuidad al cambiar de micro-frontend (mismo origen), modo invisible e i18n.",
1370
+ G_COV_7: "Login Setup: configura tu funci\xF3n de login en Ctrl+3 \u2192 Login Setup y el grabador a\xF1ade los bloques before()/beforeEach() a cada test nuevo.",
1371
+ // TODO: translate (fr)
1372
+ G_SEC_NOTCOVERED: "\u{1F6AB} Qu\xE9 NO cubre (por ahora)",
1373
+ G_NC_1: "Or\xEDgenes distintos / subdominios (solo mismo origen).",
1374
+ G_NC_2: "Subida de ficheros (selectFile), arrastrar y soltar, y hover.",
1375
+ G_NC_3: "La tecla Tab (Cypress no la soporta en .type()).",
1376
+ G_NC_4: "Peticiones DELETE (se ignoran a prop\xF3sito).",
1377
+ G_NC_5: "iframes y Shadow DOM de terceros pueden no capturarse."
1378
+ }
1379
+ };
1380
+
1381
+ // src/i18n/it.ts
1382
+ var I18N_IT = {
1383
+ MAIN_FRAME: {
1384
+ SETTINGS: "Impostazioni",
1385
+ SHOW_ADVANCED_EDITOR: "Editor avanzato",
1386
+ DIALOG_SAVED_TESTS: "Test salvati",
1387
+ DIALOG_COMMANDS: "Anteprima comandi Cypress",
1388
+ DIALOG_SAVE: "Salvare la registrazione?"
1389
+ },
1390
+ SAVE_TEST: {
1391
+ DESC_LABEL: "Descrizione del test",
1392
+ CANCEL: "Annulla",
1393
+ ASK: "Salvare il test registrato?",
1394
+ YES_CONTINUE: "S\xEC, continua",
1395
+ NO_DISCARD: "No, annulla",
1396
+ DESC_PLACEHOLDER: "Es: Login riuscito con credenziali valide",
1397
+ TAGS_LABEL: "Etichette (opzionale, per filtrare dopo):",
1398
+ TAGS_PLACEHOLDER: "smoke, login, regressione\u2026",
1399
+ ADD_TAG: "+ Aggiungi",
1400
+ NO_TAGS: "Nessuna etichetta",
1401
+ SAVE_BTN: "\u{1F4BE} Salva",
1402
+ SAVE_AND_EDIT: "\u{1F4DD} Salva e modifica",
1403
+ REMOVE_TAG_TITLE: "Rimuovi",
1404
+ NOTES_LABEL: "Descrizione / Note (opzionale):",
1405
+ NOTES_PLACEHOLDER: "Cosa valida questo test, condizioni preliminari, ecc.",
1406
+ TICKET_LABEL: "Ticket / Issue (opzionale):",
1407
+ TICKET_PLACEHOLDER: "Es: PROJ-123, #42",
1408
+ TICKET_WARN: "ID non valido per il provider configurato (verr\xE0 salvato comunque)",
1409
+ // TODO: translate
1410
+ CONFIRM_DISCARD: "Sei sicuro di voler scartare questa registrazione? Tutti i passi registrati andranno persi.",
1411
+ CONFIRM_DISCARD_BTN: "S\xEC, scarta",
1412
+ BACK_BTN: "Indietro",
1413
+ CONTINUE_RECORDING_BTN: "\u23FA Continua a registrare"
1414
+ },
1415
+ TEST_EDITOR: {
1416
+ NO_TAGS: "Nessuna etichetta",
1417
+ SELECTED_SINGULAR: "selezionato",
1418
+ SELECTED_PLURAL: "selezionati",
1419
+ DESCRIBE_PLACEHOLDER: "Nome del describe (opzionale)",
1420
+ COPY_DESCRIBE: "\u{1F5C2} Copia describe()",
1421
+ MULTI_SELECT: "\u{1F5C2} Multi-selezione",
1422
+ CANCEL_SELECT: "\u2715 Annulla",
1423
+ COPY_CMDS_BTN: "\u{1F4CB} Copia comandi",
1424
+ COPY_ICPS_BTN: "\u{1F4CB} Copia interceptor",
1425
+ DEFAULT_DESCRIBE: "Suite di test",
1426
+ NO_TESTS: "Nessun test salvato",
1427
+ DELETE_TITLE: "Elimina",
1428
+ GROUP_BY_TICKET: "\u{1F3AB} Raggruppa per ticket",
1429
+ UNGROUP_TICKET: "\u{1F3AB} Separa",
1430
+ NO_TICKET: "Senza ticket",
1431
+ TICKET_LINK_TITLE: "Apri ticket"
1432
+ },
1433
+ CONFIG: {
1434
+ LANG_SECTION: "\u{1F310} Lingua",
1435
+ LANG_FIELD: "Interfaccia",
1436
+ HTTP_SECTION: "\u26A1 HTTP Avanzato",
1437
+ HTTP_TITLE: "Validazioni del body",
1438
+ HTTP_SUB: "GET \u2192 risposta \xB7 POST/PUT \u2192 richiesta",
1439
+ FIXTURE_SECTION: "\u{1F9EA} Fixture HTTP",
1440
+ FIXTURE_TITLE: "Registra le risposte come fixture",
1441
+ FIXTURE_SUB: "Le GET vengono salvate in cypress/fixtures e stubbate con cy.intercept({ fixture }).",
1442
+ SELECTOR_SECTION: "\u{1F3AF} Strategia selettore",
1443
+ SELECTOR_LABEL: "Attributo preferito per cy.get()",
1444
+ SELECTOR_OPT_DATACY: "data-cy (predefinito)",
1445
+ SELECTOR_OPT_TESTID: "data-testid",
1446
+ SELECTOR_OPT_ARIA: "aria-label",
1447
+ SELECTOR_OPT_ID: "id (#elemento)",
1448
+ SELECTOR_HINT: "Il registratore cercher\xE0 prima questo attributo. Se assente, prover\xE0 gli altri.",
1449
+ FOLDER_SECTION: "\u{1F4C1} Cartella Cypress",
1450
+ FOLDER_CONNECTED: "connesso \u2014",
1451
+ FOLDER_NOT_SET: "non configurato",
1452
+ FOLDER_CHANGE_BTN: "\u{1F4C1} Cambia cartella",
1453
+ FOLDER_SELECT_BTN: "\u{1F4C1} Seleziona cartella",
1454
+ FOLDER_REVOKE_BTN: "\u2715 Revoca accesso",
1455
+ DATA_SECTION: "\u{1F4BE} Dati",
1456
+ DATA_DESC: "Esporta tutti i tuoi test in JSON o importa un backup.",
1457
+ EXPORT_BTN: "\u2B06\uFE0F Esporta test",
1458
+ EXPORT_DIALOG_TITLE: "\u2B06\uFE0F Esporta test",
1459
+ EXPORT_MODE_ALL: "Tutto",
1460
+ EXPORT_MODE_MANUAL: "Selezione manuale",
1461
+ EXPORT_MODE_TAGS: "Per tag",
1462
+ EXPORT_ALL_DESC: "Verranno esportati tutti i test salvati.",
1463
+ EXPORT_COUNT: "Da esportare:",
1464
+ EXPORT_CONFIRM: "\u2B06\uFE0F Esporta",
1465
+ EXPORT_CANCEL: "Annulla",
1466
+ EXPORT_EMPTY: "Nessun test da esportare.",
1467
+ EXPORT_NO_TAGS: "Nessun tag disponibile.",
1468
+ EXPORT_TAGS_HINT: "Seleziona uno o pi\xF9 tag per vedere quali test verranno esportati.",
1469
+ EXPORT_RESULT_LABEL: "Test che verranno esportati:",
1470
+ IMPORT_BTN: "\u2B07\uFE0F Importa test",
1471
+ FOLDER_UPDATED_TOAST: "\u2713 Cartella Cypress aggiornata",
1472
+ FOLDER_ERROR_TOAST: "Errore durante l'accesso alla cartella",
1473
+ IMPORT_SUCCESS: "Dati importati correttamente.",
1474
+ IMPORT_ERROR: "Errore durante l'importazione.",
1475
+ JSON_INVALID: "Il file non \xE8 un JSON valido.",
1476
+ JSON_BAD_FORMAT: "Il file non ha il formato previsto.",
1477
+ SMART_SELECTOR_SECTION: "\u{1F50D} Selettore intelligente",
1478
+ SMART_SELECTOR_TITLE: "Selettore intelligente",
1479
+ SMART_SELECTOR_SUB: "Mostra un selettore quando si fa clic su elementi senza selettore valido.",
1480
+ START_HIDDEN_SECTION: "\u{1F441} Visibilit\xE0 del widget",
1481
+ START_HIDDEN_TITLE: "Avvia nascosto",
1482
+ START_HIDDEN_SUB: "Il widget si avvia invisibile. Usa Ctrl+Shift+E per mostrarlo o nasconderlo.",
1483
+ RESUME_TTL_SECTION: "\u23F1 Continuit\xE0 di registrazione",
1484
+ RESUME_TTL_LABEL: "Riprendi senza chiedere (minuti)",
1485
+ RESUME_TTL_HINT: "Se ricarichi o cambi progetto, una registrazione attiva riprende senza chiedere entro questo intervallo. Trascorso, ti chieder\xE0 se continuare o annullare.",
1486
+ WIDGET_POSITION_SECTION: "\u{1F9F2} Posizione del widget",
1487
+ WIDGET_POSITION_HINT: "Trascina il pulsante di registrazione per spostarlo. La posizione viene ricordata.",
1488
+ WIDGET_POSITION_RESET_BTN: "\u21BA Reimposta posizione",
1489
+ WIDGET_POSITION_RESET_DONE: "\u2713 Posizione reimpostata",
1490
+ ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue tracker",
1491
+ ISSUE_TRACKER_TITLE: "Collega i test ai ticket",
1492
+ ISSUE_TRACKER_SUB: "Aggiungi un ID ticket al salvataggio e genera un link cliccabile nell'elenco.",
1493
+ ISSUE_TRACKER_PROVIDER: "Provider",
1494
+ ISSUE_TRACKER_BASE_URL: "URL base",
1495
+ ISSUE_TRACKER_BASE_URL_PH: "Es: https://mioprogetto.atlassian.net",
1496
+ LOGIN_SETUP_SECTION: "\u{1F510} Login setup",
1497
+ LOGIN_SETUP_NOT_CONFIGURED: "Non configurato",
1498
+ LOGIN_SETUP_SET_UP_BTN: "Configura",
1499
+ LOGIN_SETUP_TITLE: "Configurazione del login",
1500
+ LOGIN_SETUP_CREATE_SCAFFOLD: "Crea scaffold",
1501
+ LOGIN_SETUP_SELECT_EXISTING: "Seleziona file esistente",
1502
+ LOGIN_SETUP_FILE_NAME_LABEL: "Nome del file",
1503
+ LOGIN_SETUP_FILE_NAME_PH: "Es: cypress/common-services/login.service.ts",
1504
+ LOGIN_SETUP_RESCAN: "\u{1F504} Re-scansiona",
1505
+ LOGIN_SETUP_FUNCTIONS_DETECTED: "Funzioni rilevate",
1506
+ LOGIN_SETUP_BLOCK_ASSIGN: "Assegnazione dei blocchi",
1507
+ LOGIN_SETUP_NO_FUNCTIONS: "Nessuna funzione esportata trovata. Compila lo scaffold e ri-scansiona.",
1508
+ LOGIN_SETUP_BEFORE_LABEL: "Funzione before() (una volta per suite)",
1509
+ LOGIN_SETUP_BEFORE_EACH_LABEL: "Funzione beforeEach() (prima di ogni test)",
1510
+ LOGIN_SETUP_NONE_OPTION: "\u2014 Nessuna \u2014",
1511
+ LOGIN_SETUP_SUMMARY: "File: {file} \xB7 before: {before} \xB7 beforeEach: {beforeEach}",
1512
+ LOGIN_SETUP_SAVE_BTN: "\u{1F4BE} Salva",
1513
+ LOGIN_SETUP_CLEAR_BTN: "Rimuovi configurazione",
1514
+ LOGIN_SETUP_CANCEL_BTN: "Annulla",
1515
+ LOGIN_SETUP_SOURCE_LABEL: "Sorgente del file di login",
1516
+ LOGIN_SETUP_CREATE_SUB: "Genera uno scaffold con funzioni di esempio",
1517
+ LOGIN_SETUP_SELECT_SUB: "Punta a un file di servizio di login esistente",
1518
+ LOGIN_SETUP_INJECT_TITLE: "Aggiungere i blocchi di login?",
1519
+ LOGIN_SETUP_INJECT_TEXT: "Questo file non contiene i blocchi di login configurati. Vuoi aggiungere l'import e i blocchi before/beforeEach ora?",
1520
+ LOGIN_SETUP_INJECT_CONFIRM: "S\xEC, aggiungi"
1521
+ },
1522
+ SELECTOR_PICKER: {
1523
+ TITLE: "Seleziona un elemento DOM",
1524
+ PREVIEW_LABEL: "navigare",
1525
+ CONFIRM_HINT: "confermare",
1526
+ CANCEL_HINT: "annullare",
1527
+ QUALITY_EXCELLENT: "Eccellente \u2014 attributo di test presente (data-cy / data-testid / aria-label)",
1528
+ QUALITY_GOOD: "Buono \u2014 id valido",
1529
+ QUALITY_ACCEPTABLE: "Accettabile \u2014 solo classi CSS",
1530
+ QUALITY_POOR: "Sconsigliato \u2014 solo tag o stile inline"
1531
+ },
1532
+ TEST_PREVISUALIZER: {
1533
+ INTERCEPTORS: "Interceptor",
1534
+ COPY_CMDS_BTN: "\u{1F4CB} Copia comandi",
1535
+ SHOW_INTERCEPTORS: "\u25BC Vedi interceptor",
1536
+ HIDE_INTERCEPTORS: "\u25B2 Nascondi interceptor",
1537
+ SECTION_COMMANDS: "Comandi",
1538
+ NO_CMDS_YET: "Ancora nessun comando",
1539
+ NO_ICP_SHORT: "Nessun interceptor",
1540
+ COPY_ICP_BTN: "\u{1F4CB} Copia interceptor",
1541
+ UP_TITLE: "Su",
1542
+ DOWN_TITLE: "Gi\xF9",
1543
+ DEL_TITLE: "Elimina"
1544
+ },
1545
+ ADVANCED_EDITOR: {
1546
+ REAUTH_BTN: "\u{1F513} Riattiva accesso",
1547
+ PERMISSION_EXPIRED: "\u{1F511} Autorizzazione scaduta",
1548
+ PERMISSION_EXPIRED_HINT: "Clicca per riattivare l'accesso alla cartella Cypress.",
1549
+ NO_ACCESS: "\u{1F512} Nessun accesso ai file locali",
1550
+ NO_ACCESS_HINT: "Configura l'accesso in \u2699\uFE0F Config.",
1551
+ NO_FILES: "Nessun file",
1552
+ SELECT_FILE: "\u2190 Seleziona un file dall'albero",
1553
+ IT_LABEL: "\u{1F9EA} it() da inserire:",
1554
+ COPY_IT_BTN: "\u{1F4CB} Copia it()",
1555
+ BEFORE_EACH_LABEL: "\u{1F500} beforeEach() interceptor:",
1556
+ COPY_ICP_BTN: "\u{1F4CB} Copia interceptor",
1557
+ INSERT_BTN: "\u{1F4BE} Inserisci nel file",
1558
+ EDIT_MANUAL_BTN: "\u270F\uFE0F Modifica manualmente",
1559
+ CLOSE_BTN: "\u2715 Chiudi",
1560
+ NEW_FILE_BTN: "+ Nuovo file",
1561
+ NEW_FOLDER_BTN: "+ Nuova cartella",
1562
+ REFRESH_BTN: "\u21BB Aggiorna",
1563
+ NEW_FILE_PLACEHOLDER: "nome-del-test",
1564
+ NEW_FOLDER_PLACEHOLDER: "nome-cartella",
1565
+ NEW_FILE_CONFIRM: "Crea",
1566
+ NEW_FILE_CANCEL: "Annulla"
1567
+ },
1568
+ FILE_PREVIEW: {
1569
+ NO_FILE: "Nessun file",
1570
+ COPY_TITLE: "Copia il contenuto dell'editor",
1571
+ BLOCK_IT: "\u{1F9EA} it()",
1572
+ COPY_BTN: "\u{1F4CB} Copia",
1573
+ BLOCK_BEFORE_EACH: "\u{1F500} beforeEach()",
1574
+ NO_CHANGES: "Nessuna modifica rispetto all'originale",
1575
+ NO_CHANGES_SHORT: "Nessuna modifica",
1576
+ LAUNCH_BTN: "\u25B6 Esegui test",
1577
+ LAUNCH_LOCAL_ONLY: "Spostati in locale per poter testare",
1578
+ LAUNCH_RUNNING: "\u23F3 Esecuzione\u2026",
1579
+ LAUNCH_PASSED: "\u2713 Test superato",
1580
+ LAUNCH_FAILED: "\u2717 Test fallito",
1581
+ LAUNCH_NO_RUNNER: "Nessun runner locale rilevato (l'hai avviato?)",
1582
+ DIFF_BTN: "\u{1F4CA} Diff",
1583
+ SAVE_BTN: "\u{1F4BE} Salva",
1584
+ CLOSE_BTN: "\u2715 Chiudi",
1585
+ BACK_TO_EDITOR: "\u2190 Torna all'editor",
1586
+ INSERT_BTN: "\u{1FA84} Inserisci blocchi",
1587
+ INSERT_TITLE: "Inserisci it() e beforeEach() nel contenuto dell'editor",
1588
+ INSERT_DONE: "Blocchi inseriti nell'editor",
1589
+ INSERT_ERROR: "Nessun blocco describe() valido trovato nel file"
1590
+ },
1591
+ RECORDER: {
1592
+ FS_TITLE: "\u{1F4C1} Accesso ai file",
1593
+ FS_LATER_BTN: "Non ora",
1594
+ FS_SELECT_BTN: "\u{1F4C1} Seleziona cartella",
1595
+ FS_SUCCESS_TOAST: "\u2713 Cartella Cypress configurata",
1596
+ FS_ERROR_TOAST: "Errore durante l'accesso alla cartella",
1597
+ FS_INTRO_HTML: `L'<strong style="color:#e6edf3">editor avanzato</strong> pu\xF2 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.`,
1598
+ 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:`,
1599
+ FS_TREE_PICK_HINT: "\u2190 seleziona questa cartella",
1600
+ FS_TREE_READ_HINT: "\u2190 l'estensione legger\xE0 qui",
1601
+ FS_PERMISSION_NOTE: "Il permesso viene salvato nel browser e non sar\xE0 richiesto di nuovo.",
1602
+ ASSERTION_SECTION: "\u2795 Aggiungi asserzione",
1603
+ ASSERT_SELECTOR_PH: 'selettore, es: [data-cy="btn"]',
1604
+ ASSERT_VALUE_PH: "valore atteso",
1605
+ ASSERT_ADD_BTN: "\u2795 Aggiungi",
1606
+ FILE_EDITOR_TITLE: "\u270F\uFE0F Editor di file",
1607
+ FILE_SAVED_TOAST: "\u2713 File salvato",
1608
+ FILE_SAVE_ERROR_TOAST: "Errore durante il salvataggio",
1609
+ FIXTURES_WRITTEN_TOAST: "\u2713 Fixture scritte in cypress/fixtures",
1610
+ FIXTURES_NO_FOLDER_TOAST: "Impossibile scrivere le fixture (configura la cartella Cypress)",
1611
+ FILE_UPLOAD_MANUAL_TOAST: "Aggiungi {files} a cypress/fixtures/ prima di eseguire il test.",
1612
+ // TODO: translate
1613
+ FILE_UPLOAD_COPIED_TOAST: "{files} copiato/i in cypress/fixtures/.",
1614
+ // TODO: translate
1615
+ FILE_UPLOAD_COPY_ERROR_TOAST: "Impossibile copiare {files} in cypress/fixtures/. Aggiungilo manualmente.",
1616
+ // TODO: translate
1617
+ BTN_CONFIG: "Config",
1618
+ BTN_FILES: "File",
1619
+ BTN_COMMANDS: "Comandi",
1620
+ BTN_TESTS: "Test",
1621
+ PAUSE_TITLE: "Pausa (Ctrl+P)",
1622
+ RESUME_TITLE: "Riprendi (Ctrl+P)",
1623
+ BADGE_PAUSED: "\u23F8 PAUSA",
1624
+ BADGE_REC: "\u25CF REC",
1625
+ STOP_TITLE: "Ferma (Ctrl+R)",
1626
+ START_TITLE: "Registra (Ctrl+R)",
1627
+ SESSION_RESUME_TITLE: "\u23FA Registrazione in corso",
1628
+ SESSION_RESUME_TEXT: "C'\xE8 una registrazione attiva non terminata.",
1629
+ SESSION_RESUME_COUNT: "comandi catturati",
1630
+ SESSION_CONTINUE_BTN: "Continua a registrare",
1631
+ SESSION_DISCARD_BTN: "Annulla",
1632
+ BTN_HELP: "Aiuto",
1633
+ RECOVER_BTN: "Recupera",
1634
+ RECOVER_TITLE: "Recupera l\u2019ultima registrazione interrotta: {count} comandi ({time})",
1635
+ RECOVER_TIME_NOW: "proprio ora",
1636
+ RECOVER_TIME_MINUTES: "{m} min fa"
1637
+ },
1638
+ HELP: {
1639
+ TITLE: "\u2753 Aiuto \u2014 Guida rapida",
1640
+ INTRO: "Tutto ci\xF2 che il registratore sa fare.",
1641
+ SEC_RECORDING: "\u23FA Registrare",
1642
+ RECORDING_1: "Premi \u23FA (o Ctrl+R) per iniziare; \u23F9 per fermare e salvare.",
1643
+ RECORDING_2: "Pausa / ripresa con \u23F8 (o Ctrl+P).",
1644
+ SEC_SHORTCUTS: "\u2328\uFE0F Scorciatoie da tastiera",
1645
+ SC_RECORD: "Ctrl+R \u2014 Registra / ferma",
1646
+ SC_PAUSE: "Ctrl+P \u2014 Pausa / ripresa",
1647
+ SC_TESTS: "Ctrl+1 \u2014 Pannello test salvati",
1648
+ SC_COMMANDS: "Ctrl+2 \u2014 Pannello comandi",
1649
+ SC_CONFIG: "Ctrl+3 \u2014 Impostazioni",
1650
+ SC_VISIBILITY: "Ctrl+Shift+E \u2014 Mostra / nascondi il widget",
1651
+ SC_HELP: "Ctrl+Shift+H \u2014 Questo aiuto",
1652
+ SEC_CAPTURED: "\u{1F3AF} Cosa viene registrato",
1653
+ CAP_CLICK: "Click \u2192 .click()",
1654
+ CAP_DBLCLICK: "Doppio click \u2192 .dblclick()",
1655
+ CAP_RIGHTCLICK: "Click destro \u2192 .rightclick()",
1656
+ CAP_TYPE: "Digitare in un campo \u2192 .clear().type(...)",
1657
+ CAP_CHECK: "Checkbox / radio \u2192 .check() / .uncheck()",
1658
+ CAP_SELECT: "<select> \u2192 .select(...)",
1659
+ CAP_KEYS: 'Invio / Esc \u2192 .type("{enter}") / ("{esc}")',
1660
+ CAP_ROUTE: "Cambio di rotta (SPA) \u2192 cy.url().should(...)",
1661
+ CAP_HTTP: "fetch / XHR \u2192 cy.intercept + cy.wait",
1662
+ SEC_ASSERT: "\u2705 Asserzioni",
1663
+ ASSERT_1: "Alt+click su un elemento per verificarlo senza eseguire la sua azione (testo, valore, checked o visibile).",
1664
+ ASSERT_2: "Oppure usa il costruttore di asserzioni nel pannello Comandi.",
1665
+ SEC_PANELS: "\u{1F5C2} Pannelli",
1666
+ PANEL_TESTS: "\u{1F4CB} Test \u2014 salvati: filtra per tag, copia, combina, esporta.",
1667
+ PANEL_COMMANDS: "\u2328\uFE0F Comandi \u2014 registrazione corrente: riordina, elimina, aggiungi asserzioni.",
1668
+ PANEL_CONFIG: "\u2699\uFE0F Config \u2014 lingua, selettore, HTTP, cartella Cypress, login setup, dati, visibilit\xE0, posizione.",
1669
+ PANEL_FILES: "\u{1F4C1} File \u2014 inserisci test nei tuoi .cy.ts e avvia il runner.",
1670
+ SEC_SELECTOR: "\u{1F50E} Selettori",
1671
+ SELECTOR_1: "Scegli l'attributo preferito (data-cy, data-testid, aria-label, id) in Config.",
1672
+ SELECTOR_2: "Se un click non ha un selettore affidabile, appare un picker per scegliere l'antenato migliore.",
1673
+ SEC_DATA: "\u{1F4BE} Dati",
1674
+ DATA_1: "Esporta i test in JSON (tutto / selezione / per tag).",
1675
+ DATA_2: "Importa un JSON: si fonde con i tuoi dati (non si cancella nulla).",
1676
+ SEC_ADVANCED: "\u{1F680} Avanzato",
1677
+ ADV_INVISIBLE: "Modalit\xE0 invisibile: start-hidden + Ctrl+Shift+E per registrare in produzione senza disturbare.",
1678
+ ADV_RUNNER: "Runner locale: npx lib-e2e-cypress-runner per eseguire uno spec headless dall'editor.",
1679
+ ADV_CROSSAPP: "Cross-app: la registrazione sopravvive al cambio di micro-frontend (stessa origine).",
1680
+ ADV_DRAG: "Trascina il pulsante \u23FA per spostare il widget; la posizione viene ricordata.",
1681
+ ADV_LOGIN: "Login Setup (Ctrl+3): apunta a tu servicio de login; el grabador inyecta before()/beforeEach() autom\xE1ticamente en cada test nuevo.",
1682
+ // TODO: translate (it)
1683
+ CLOSE: "Chiudi",
1684
+ TAB_REFERENCE: "Riferimento rapido",
1685
+ TAB_GUIDE: "Guida all'uso",
1686
+ // TODO: translate (it) — usage guide body kept in Spanish for now.
1687
+ GUIDE_INTRO: "C\xF3mo sacarle partido al grabador, qu\xE9 cubre y qu\xE9 no.",
1688
+ G_SEC_WORKFLOW: "\u{1F9ED} Flujo de trabajo",
1689
+ G_WF_1: "1. Pulsa \u23FA (o Ctrl+R) para empezar a grabar.",
1690
+ G_WF_2: "2. Usa tu app como un usuario: clicks, formularios, navegaci\xF3n. Cada acci\xF3n se convierte en un comando Cypress.",
1691
+ G_WF_3: "3. A\xF1ade verificaciones con Alt+click sobre lo que quieras comprobar.",
1692
+ G_WF_4: "4. Pulsa \u23F9 para parar; ponle nombre y tags, y gu\xE1rdalo.",
1693
+ G_WF_5: "5. En \u{1F4C1} Ficheros, inserta el test en un .cy.ts o l\xE1nzalo con el runner local.",
1694
+ G_SEC_COVERED: "\u2705 Qu\xE9 cubre",
1695
+ G_COV_1: "Clicks, doble-click, click derecho, inputs de texto, checkbox/radio, select y teclas Enter/Escape.",
1696
+ G_COV_2: "Navegaci\xF3n SPA (pushState/replaceState/popstate) \u2192 cy.url().should(...).",
1697
+ G_COV_3: "Llamadas fetch/XHR (GET/POST/PUT) \u2192 cy.intercept + cy.wait, con validaci\xF3n de body opcional.",
1698
+ G_COV_4: "Selector fiable (data-cy/testid/aria/id) y picker cuando no hay uno claro.",
1699
+ G_COV_5: "Aserciones autom\xE1ticas (Alt+click) y constructor manual.",
1700
+ G_COV_6: "Continuidad al cambiar de micro-frontend (mismo origen), modo invisible e i18n.",
1701
+ G_COV_7: "Login Setup: configura tu funci\xF3n de login en Ctrl+3 \u2192 Login Setup y el grabador a\xF1ade los bloques before()/beforeEach() a cada test nuevo.",
1702
+ // TODO: translate (it)
1703
+ G_SEC_NOTCOVERED: "\u{1F6AB} Qu\xE9 NO cubre (por ahora)",
1704
+ G_NC_1: "Or\xEDgenes distintos / subdominios (solo mismo origen).",
1705
+ G_NC_2: "Subida de ficheros (selectFile), arrastrar y soltar, y hover.",
1706
+ G_NC_3: "La tecla Tab (Cypress no la soporta en .type()).",
1707
+ G_NC_4: "Peticiones DELETE (se ignoran a prop\xF3sito).",
1708
+ G_NC_5: "iframes y Shadow DOM de terceros pueden no capturarse."
1709
+ }
1710
+ };
1711
+
1712
+ // src/i18n/de.ts
1713
+ var I18N_DE = {
1714
+ MAIN_FRAME: {
1715
+ SETTINGS: "Einstellungen",
1716
+ SHOW_ADVANCED_EDITOR: "Erweiterter Editor",
1717
+ DIALOG_SAVED_TESTS: "Gespeicherte Tests",
1718
+ DIALOG_COMMANDS: "Cypress-Befehle Vorschau",
1719
+ DIALOG_SAVE: "Aufzeichnung speichern?"
1720
+ },
1721
+ SAVE_TEST: {
1722
+ DESC_LABEL: "Testbeschreibung",
1723
+ CANCEL: "Abbrechen",
1724
+ ASK: "Aufgezeichneten Test speichern?",
1725
+ YES_CONTINUE: "Ja, weiter",
1726
+ NO_DISCARD: "Nein, verwerfen",
1727
+ DESC_PLACEHOLDER: "Z. B.: Erfolgreiche Anmeldung mit g\xFCltigen Zugangsdaten",
1728
+ TAGS_LABEL: "Tags (optional, zum sp\xE4teren Filtern):",
1729
+ TAGS_PLACEHOLDER: "smoke, login, regression\u2026",
1730
+ ADD_TAG: "+ Hinzuf\xFCgen",
1731
+ NO_TAGS: "Keine Tags",
1732
+ SAVE_BTN: "\u{1F4BE} Speichern",
1733
+ SAVE_AND_EDIT: "\u{1F4DD} Speichern und bearbeiten",
1734
+ REMOVE_TAG_TITLE: "Entfernen",
1735
+ NOTES_LABEL: "Beschreibung / Notizen (optional):",
1736
+ NOTES_PLACEHOLDER: "Was dieser Test validiert, Voraussetzungen usw.",
1737
+ TICKET_LABEL: "Ticket / Issue (optional):",
1738
+ TICKET_PLACEHOLDER: "Z. B.: PROJ-123, #42",
1739
+ TICKET_WARN: "Ung\xFCltige ID f\xFCr den konfigurierten Anbieter (wird trotzdem gespeichert)",
1740
+ // TODO: translate
1741
+ CONFIRM_DISCARD: "Sind Sie sicher, dass Sie diese Aufzeichnung verwerfen m\xF6chten? Alle aufgezeichneten Schritte gehen verloren.",
1742
+ CONFIRM_DISCARD_BTN: "Ja, verwerfen",
1743
+ BACK_BTN: "Zur\xFCck",
1744
+ CONTINUE_RECORDING_BTN: "\u23FA Aufnahme fortsetzen"
1745
+ },
1746
+ TEST_EDITOR: {
1747
+ NO_TAGS: "Keine Tags",
1748
+ SELECTED_SINGULAR: "ausgew\xE4hlt",
1749
+ SELECTED_PLURAL: "ausgew\xE4hlt",
1750
+ DESCRIBE_PLACEHOLDER: "describe-Name (optional)",
1751
+ COPY_DESCRIBE: "\u{1F5C2} describe() kopieren",
1752
+ MULTI_SELECT: "\u{1F5C2} Mehrfachauswahl",
1753
+ CANCEL_SELECT: "\u2715 Abbrechen",
1754
+ COPY_CMDS_BTN: "\u{1F4CB} Befehle kopieren",
1755
+ COPY_ICPS_BTN: "\u{1F4CB} Interceptors kopieren",
1756
+ DEFAULT_DESCRIBE: "Test-Suite",
1757
+ NO_TESTS: "Keine gespeicherten Tests",
1758
+ DELETE_TITLE: "L\xF6schen",
1759
+ GROUP_BY_TICKET: "\u{1F3AB} Nach Ticket gruppieren",
1760
+ UNGROUP_TICKET: "\u{1F3AB} Gruppierung aufheben",
1761
+ NO_TICKET: "Kein Ticket",
1762
+ TICKET_LINK_TITLE: "Ticket \xF6ffnen"
1763
+ },
1764
+ CONFIG: {
1765
+ LANG_SECTION: "\u{1F310} Sprache",
1766
+ LANG_FIELD: "Oberfl\xE4che",
1767
+ HTTP_SECTION: "\u26A1 Erweitertes HTTP",
1768
+ HTTP_TITLE: "Body-Validierungen",
1769
+ HTTP_SUB: "GET \u2192 Antwort \xB7 POST/PUT \u2192 Anfrage",
1770
+ FIXTURE_SECTION: "\u{1F9EA} HTTP-Fixtures",
1771
+ FIXTURE_TITLE: "Antworten als Fixtures aufzeichnen",
1772
+ FIXTURE_SUB: "GET-Antworten werden in cypress/fixtures gespeichert und mit cy.intercept({ fixture }) gestubbt.",
1773
+ SELECTOR_SECTION: "\u{1F3AF} Selector-Strategie",
1774
+ SELECTOR_LABEL: "Bevorzugtes Attribut f\xFCr cy.get()",
1775
+ SELECTOR_OPT_DATACY: "data-cy (Standard)",
1776
+ SELECTOR_OPT_TESTID: "data-testid",
1777
+ SELECTOR_OPT_ARIA: "aria-label",
1778
+ SELECTOR_OPT_ID: "id (#element)",
1779
+ SELECTOR_HINT: "Der Recorder sucht zuerst nach diesem Attribut. Falls nicht gefunden, versucht er die anderen.",
1780
+ FOLDER_SECTION: "\u{1F4C1} Cypress-Ordner",
1781
+ FOLDER_CONNECTED: "verbunden \u2014",
1782
+ FOLDER_NOT_SET: "nicht konfiguriert",
1783
+ FOLDER_CHANGE_BTN: "\u{1F4C1} Ordner wechseln",
1784
+ FOLDER_SELECT_BTN: "\u{1F4C1} Ordner ausw\xE4hlen",
1785
+ FOLDER_REVOKE_BTN: "\u2715 Zugriff widerrufen",
1786
+ DATA_SECTION: "\u{1F4BE} Daten",
1787
+ DATA_DESC: "Exportieren Sie alle Tests als JSON oder importieren Sie ein Backup.",
1788
+ EXPORT_BTN: "\u2B06\uFE0F Tests exportieren",
1789
+ EXPORT_DIALOG_TITLE: "\u2B06\uFE0F Tests exportieren",
1790
+ EXPORT_MODE_ALL: "Alle",
1791
+ EXPORT_MODE_MANUAL: "Manuelle Auswahl",
1792
+ EXPORT_MODE_TAGS: "Nach Tags",
1793
+ EXPORT_ALL_DESC: "Alle gespeicherten Tests werden exportiert.",
1794
+ EXPORT_COUNT: "Zu exportieren:",
1795
+ EXPORT_CONFIRM: "\u2B06\uFE0F Exportieren",
1796
+ EXPORT_CANCEL: "Abbrechen",
1797
+ EXPORT_EMPTY: "Keine Tests zum Exportieren.",
1798
+ EXPORT_NO_TAGS: "Keine Tags verf\xFCgbar.",
1799
+ EXPORT_TAGS_HINT: "W\xE4hle ein oder mehrere Tags, um zu sehen, welche Tests exportiert werden.",
1800
+ EXPORT_RESULT_LABEL: "Diese Tests werden exportiert:",
1801
+ IMPORT_BTN: "\u2B07\uFE0F Tests importieren",
1802
+ FOLDER_UPDATED_TOAST: "\u2713 Cypress-Ordner aktualisiert",
1803
+ FOLDER_ERROR_TOAST: "Fehler beim Zugriff auf den Ordner",
1804
+ IMPORT_SUCCESS: "Daten erfolgreich importiert.",
1805
+ IMPORT_ERROR: "Fehler beim Importieren.",
1806
+ JSON_INVALID: "Die Datei ist kein g\xFCltiges JSON.",
1807
+ JSON_BAD_FORMAT: "Die Datei hat nicht das erwartete Format.",
1808
+ SMART_SELECTOR_SECTION: "\u{1F50D} Intelligenter Selektor",
1809
+ SMART_SELECTOR_TITLE: "Intelligenter Selektor",
1810
+ SMART_SELECTOR_SUB: "Zeigt ein Auswahlfeld, wenn auf Elemente ohne g\xFCltigen Selektor geklickt wird.",
1811
+ START_HIDDEN_SECTION: "\u{1F441} Widget-Sichtbarkeit",
1812
+ START_HIDDEN_TITLE: "Versteckt starten",
1813
+ START_HIDDEN_SUB: "Das Widget startet unsichtbar. Verwenden Sie Ctrl+Shift+E zum Ein-/Ausblenden.",
1814
+ RESUME_TTL_SECTION: "\u23F1 Aufzeichnungskontinuit\xE4t",
1815
+ RESUME_TTL_LABEL: "Ohne Nachfrage fortsetzen (Minuten)",
1816
+ RESUME_TTL_HINT: "Wenn Sie neu laden oder das Projekt wechseln, wird eine aktive Aufzeichnung innerhalb dieses Zeitfensters ohne Nachfrage fortgesetzt. Danach werden Sie gefragt, ob fortsetzen oder verwerfen.",
1817
+ WIDGET_POSITION_SECTION: "\u{1F9F2} Widget-Position",
1818
+ WIDGET_POSITION_HINT: "Ziehe den Aufnahme-Button, um ihn aus dem Weg zu schieben. Die Position wird gespeichert.",
1819
+ WIDGET_POSITION_RESET_BTN: "\u21BA Position zur\xFCcksetzen",
1820
+ WIDGET_POSITION_RESET_DONE: "\u2713 Position zur\xFCckgesetzt",
1821
+ ISSUE_TRACKER_SECTION: "\u{1F3AB} Issue-Tracker",
1822
+ ISSUE_TRACKER_TITLE: "Tests mit Tickets verkn\xFCpfen",
1823
+ ISSUE_TRACKER_SUB: "F\xFCge beim Speichern eine Ticket-ID hinzu und erstelle einen klickbaren Link.",
1824
+ ISSUE_TRACKER_PROVIDER: "Anbieter",
1825
+ ISSUE_TRACKER_BASE_URL: "Basis-URL",
1826
+ ISSUE_TRACKER_BASE_URL_PH: "Z. B.: https://meinprojekt.atlassian.net",
1827
+ LOGIN_SETUP_SECTION: "\u{1F510} Login setup",
1828
+ LOGIN_SETUP_NOT_CONFIGURED: "Nicht konfiguriert",
1829
+ LOGIN_SETUP_SET_UP_BTN: "Einrichten",
1830
+ LOGIN_SETUP_TITLE: "Login-Konfiguration",
1831
+ LOGIN_SETUP_CREATE_SCAFFOLD: "Scaffold erstellen",
1832
+ LOGIN_SETUP_SELECT_EXISTING: "Vorhandene Datei ausw\xE4hlen",
1833
+ LOGIN_SETUP_FILE_NAME_LABEL: "Dateiname",
1834
+ LOGIN_SETUP_FILE_NAME_PH: "Z. B.: cypress/common-services/login.service.ts",
1835
+ LOGIN_SETUP_RESCAN: "\u{1F504} Erneut scannen",
1836
+ LOGIN_SETUP_FUNCTIONS_DETECTED: "Erkannte Funktionen",
1837
+ LOGIN_SETUP_BLOCK_ASSIGN: "Blockzuweisung",
1838
+ LOGIN_SETUP_NO_FUNCTIONS: "Keine exportierten Funktionen gefunden. Scaffold ausf\xFCllen und erneut scannen.",
1839
+ LOGIN_SETUP_BEFORE_LABEL: "before()-Funktion (einmal pro Suite)",
1840
+ LOGIN_SETUP_BEFORE_EACH_LABEL: "beforeEach()-Funktion (vor jedem Test)",
1841
+ LOGIN_SETUP_NONE_OPTION: "\u2014 Keine \u2014",
1842
+ LOGIN_SETUP_SUMMARY: "Datei: {file} \xB7 before: {before} \xB7 beforeEach: {beforeEach}",
1843
+ LOGIN_SETUP_SAVE_BTN: "\u{1F4BE} Speichern",
1844
+ LOGIN_SETUP_CLEAR_BTN: "Konfiguration entfernen",
1845
+ LOGIN_SETUP_CANCEL_BTN: "Abbrechen",
1846
+ LOGIN_SETUP_SOURCE_LABEL: "Quelle der Login-Datei",
1847
+ LOGIN_SETUP_CREATE_SUB: "Scaffold mit Beispielfunktionen erstellen",
1848
+ LOGIN_SETUP_SELECT_SUB: "Auf eine vorhandene Login-Service-Datei verweisen",
1849
+ LOGIN_SETUP_INJECT_TITLE: "Login-Bl\xF6cke hinzuf\xFCgen?",
1850
+ LOGIN_SETUP_INJECT_TEXT: "Diese Datei enth\xE4lt die konfigurierten Login-Bl\xF6cke nicht. M\xF6chten Sie jetzt den Import und die before/beforeEach-Bl\xF6cke hinzuf\xFCgen?",
1851
+ LOGIN_SETUP_INJECT_CONFIRM: "Ja, hinzuf\xFCgen"
1852
+ },
1853
+ SELECTOR_PICKER: {
1854
+ TITLE: "DOM-Element ausw\xE4hlen",
1855
+ PREVIEW_LABEL: "navigieren",
1856
+ CONFIRM_HINT: "best\xE4tigen",
1857
+ CANCEL_HINT: "abbrechen",
1858
+ QUALITY_EXCELLENT: "Ausgezeichnet \u2014 Test-Attribut vorhanden (data-cy / data-testid / aria-label)",
1859
+ QUALITY_GOOD: "Gut \u2014 g\xFCltige ID",
1860
+ QUALITY_ACCEPTABLE: "Akzeptabel \u2014 nur CSS-Klassen",
1861
+ QUALITY_POOR: "Nicht empfohlen \u2014 nur Tag oder Inline-Style"
1862
+ },
1863
+ TEST_PREVISUALIZER: {
1864
+ INTERCEPTORS: "Interceptors",
1865
+ COPY_CMDS_BTN: "\u{1F4CB} Befehle kopieren",
1866
+ SHOW_INTERCEPTORS: "\u25BC Interceptors anzeigen",
1867
+ HIDE_INTERCEPTORS: "\u25B2 Interceptors ausblenden",
1868
+ SECTION_COMMANDS: "Befehle",
1869
+ NO_CMDS_YET: "Noch keine Befehle",
1870
+ NO_ICP_SHORT: "Keine Interceptors",
1871
+ COPY_ICP_BTN: "\u{1F4CB} Interceptors kopieren",
1872
+ UP_TITLE: "Nach oben",
1873
+ DOWN_TITLE: "Nach unten",
1874
+ DEL_TITLE: "L\xF6schen"
1875
+ },
1876
+ ADVANCED_EDITOR: {
1877
+ REAUTH_BTN: "\u{1F513} Zugriff reaktivieren",
1878
+ PERMISSION_EXPIRED: "\u{1F511} Berechtigung abgelaufen",
1879
+ PERMISSION_EXPIRED_HINT: "Klicken Sie, um den Zugriff auf Ihren Cypress-Ordner zu reaktivieren.",
1880
+ NO_ACCESS: "\u{1F512} Kein Zugriff auf lokale Dateien",
1881
+ NO_ACCESS_HINT: "Konfigurieren Sie den Zugriff unter \u2699\uFE0F Config.",
1882
+ NO_FILES: "Keine Dateien",
1883
+ SELECT_FILE: "\u2190 W\xE4hlen Sie eine Datei aus dem Baum",
1884
+ IT_LABEL: "\u{1F9EA} it() zum Einf\xFCgen:",
1885
+ COPY_IT_BTN: "\u{1F4CB} it() kopieren",
1886
+ BEFORE_EACH_LABEL: "\u{1F500} beforeEach() Interceptors:",
1887
+ COPY_ICP_BTN: "\u{1F4CB} Interceptors kopieren",
1888
+ INSERT_BTN: "\u{1F4BE} In Datei einf\xFCgen",
1889
+ EDIT_MANUAL_BTN: "\u270F\uFE0F Manuell bearbeiten",
1890
+ CLOSE_BTN: "\u2715 Schlie\xDFen",
1891
+ NEW_FILE_BTN: "+ Neue Datei",
1892
+ NEW_FOLDER_BTN: "+ Neuer Ordner",
1893
+ REFRESH_BTN: "\u21BB Aktualisieren",
1894
+ NEW_FILE_PLACEHOLDER: "test-name",
1895
+ NEW_FOLDER_PLACEHOLDER: "ordnername",
1896
+ NEW_FILE_CONFIRM: "Erstellen",
1897
+ NEW_FILE_CANCEL: "Abbrechen"
1898
+ },
1899
+ FILE_PREVIEW: {
1900
+ NO_FILE: "Keine Datei",
1901
+ COPY_TITLE: "Editor-Inhalt kopieren",
1902
+ BLOCK_IT: "\u{1F9EA} it()",
1903
+ COPY_BTN: "\u{1F4CB} Kopieren",
1904
+ BLOCK_BEFORE_EACH: "\u{1F500} beforeEach()",
1905
+ NO_CHANGES: "Keine \xC4nderungen gegen\xFCber dem Original",
1906
+ NO_CHANGES_SHORT: "Keine \xC4nderungen",
1907
+ LAUNCH_BTN: "\u25B6 Test starten",
1908
+ LAUNCH_LOCAL_ONLY: "Wechsle zu localhost, um Tests auszuf\xFChren",
1909
+ LAUNCH_RUNNING: "\u23F3 L\xE4uft\u2026",
1910
+ LAUNCH_PASSED: "\u2713 Test bestanden",
1911
+ LAUNCH_FAILED: "\u2717 Test fehlgeschlagen",
1912
+ LAUNCH_NO_RUNNER: "Kein lokaler Runner erkannt (gestartet?)",
1913
+ DIFF_BTN: "\u{1F4CA} Diff",
1914
+ SAVE_BTN: "\u{1F4BE} Speichern",
1915
+ CLOSE_BTN: "\u2715 Schlie\xDFen",
1916
+ BACK_TO_EDITOR: "\u2190 Zur\xFCck zum Editor",
1917
+ INSERT_BTN: "\u{1FA84} Bl\xF6cke einf\xFCgen",
1918
+ INSERT_TITLE: "it() und beforeEach() in den Editor-Inhalt einf\xFCgen",
1919
+ INSERT_DONE: "Bl\xF6cke in den Editor eingef\xFCgt",
1920
+ INSERT_ERROR: "Kein g\xFCltiger describe()-Block in der Datei gefunden"
1921
+ },
1922
+ RECORDER: {
1923
+ FS_TITLE: "\u{1F4C1} Dateizugriff",
1924
+ FS_LATER_BTN: "Nicht jetzt",
1925
+ FS_SELECT_BTN: "\u{1F4C1} Ordner ausw\xE4hlen",
1926
+ FS_SUCCESS_TOAST: "\u2713 Cypress-Ordner konfiguriert",
1927
+ FS_ERROR_TOAST: "Fehler beim Zugriff auf den Ordner",
1928
+ 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\xFCgen.',
1929
+ FS_STRUCTURE_HINT_HTML: 'W\xE4hlen Sie den Ordner, der den Unterordner <code style="background:#0d1117;padding:1px 5px;border-radius:4px;font-size:10px;color:#c9d1d9">e2e/</code> enth\xE4lt. Die Erweiterung erwartet diese Struktur:',
1930
+ FS_TREE_PICK_HINT: "\u2190 diesen Ordner ausw\xE4hlen",
1931
+ FS_TREE_READ_HINT: "\u2190 die Erweiterung liest hier",
1932
+ FS_PERMISSION_NOTE: "Die Berechtigung wird im Browser gespeichert und nicht erneut angefordert.",
1933
+ ASSERTION_SECTION: "\u2795 Assertion hinzuf\xFCgen",
1934
+ ASSERT_SELECTOR_PH: 'Selektor, z. B.: [data-cy="btn"]',
1935
+ ASSERT_VALUE_PH: "erwarteter Wert",
1936
+ ASSERT_ADD_BTN: "\u2795 Hinzuf\xFCgen",
1937
+ FILE_EDITOR_TITLE: "\u270F\uFE0F Datei-Editor",
1938
+ FILE_SAVED_TOAST: "\u2713 Datei gespeichert",
1939
+ FILE_SAVE_ERROR_TOAST: "Fehler beim Speichern",
1940
+ FIXTURES_WRITTEN_TOAST: "\u2713 Fixtures in cypress/fixtures geschrieben",
1941
+ FIXTURES_NO_FOLDER_TOAST: "Fixtures konnten nicht geschrieben werden (Cypress-Ordner konfigurieren)",
1942
+ FILE_UPLOAD_MANUAL_TOAST: "F\xFCge {files} zu cypress/fixtures/ hinzu, bevor du den Test ausf\xFChrst.",
1943
+ // TODO: translate
1944
+ FILE_UPLOAD_COPIED_TOAST: "{files} nach cypress/fixtures/ kopiert.",
1945
+ // TODO: translate
1946
+ FILE_UPLOAD_COPY_ERROR_TOAST: "{files} konnte nicht nach cypress/fixtures/ kopiert werden. F\xFCge es manuell hinzu.",
1947
+ // TODO: translate
1948
+ BTN_CONFIG: "Config",
1949
+ BTN_FILES: "Dateien",
1950
+ BTN_COMMANDS: "Befehle",
1951
+ BTN_TESTS: "Tests",
1952
+ PAUSE_TITLE: "Pausieren (Ctrl+P)",
1953
+ RESUME_TITLE: "Fortsetzen (Ctrl+P)",
1954
+ BADGE_PAUSED: "\u23F8 PAUSE",
1955
+ BADGE_REC: "\u25CF REC",
1956
+ STOP_TITLE: "Stopp (Ctrl+R)",
1957
+ START_TITLE: "Aufzeichnen (Ctrl+R)",
1958
+ SESSION_RESUME_TITLE: "\u23FA Aufzeichnung l\xE4uft",
1959
+ SESSION_RESUME_TEXT: "Es gibt eine nicht abgeschlossene aktive Aufzeichnung.",
1960
+ SESSION_RESUME_COUNT: "erfasste Befehle",
1961
+ SESSION_CONTINUE_BTN: "Weiter aufzeichnen",
1962
+ SESSION_DISCARD_BTN: "Verwerfen",
1963
+ BTN_HELP: "Hilfe",
1964
+ RECOVER_BTN: "Wiederherstellen",
1965
+ RECOVER_TITLE: "Letzte gestoppte Aufnahme wiederherstellen: {count} Befehle ({time})",
1966
+ RECOVER_TIME_NOW: "gerade eben",
1967
+ RECOVER_TIME_MINUTES: "vor {m} Min."
1968
+ },
1969
+ HELP: {
1970
+ TITLE: "\u2753 Hilfe \u2014 Kurzanleitung",
1971
+ INTRO: "Alles, was der Recorder kann.",
1972
+ SEC_RECORDING: "\u23FA Aufzeichnen",
1973
+ RECORDING_1: "Dr\xFCcke \u23FA (oder Ctrl+R) zum Starten; \u23F9 zum Stoppen und Speichern.",
1974
+ RECORDING_2: "Pause / Fortsetzen mit \u23F8 (oder Ctrl+P).",
1975
+ SEC_SHORTCUTS: "\u2328\uFE0F Tastenk\xFCrzel",
1976
+ SC_RECORD: "Ctrl+R \u2014 Aufzeichnen / stoppen",
1977
+ SC_PAUSE: "Ctrl+P \u2014 Pausieren / fortsetzen",
1978
+ SC_TESTS: "Ctrl+1 \u2014 Panel gespeicherte Tests",
1979
+ SC_COMMANDS: "Ctrl+2 \u2014 Befehle-Panel",
1980
+ SC_CONFIG: "Ctrl+3 \u2014 Einstellungen",
1981
+ SC_VISIBILITY: "Ctrl+Shift+E \u2014 Widget ein-/ausblenden",
1982
+ SC_HELP: "Ctrl+Shift+H \u2014 Diese Hilfe",
1983
+ SEC_CAPTURED: "\u{1F3AF} Was aufgezeichnet wird",
1984
+ CAP_CLICK: "Klick \u2192 .click()",
1985
+ CAP_DBLCLICK: "Doppelklick \u2192 .dblclick()",
1986
+ CAP_RIGHTCLICK: "Rechtsklick \u2192 .rightclick()",
1987
+ CAP_TYPE: "In ein Feld tippen \u2192 .clear().type(...)",
1988
+ CAP_CHECK: "Checkbox / Radio \u2192 .check() / .uncheck()",
1989
+ CAP_SELECT: "<select> \u2192 .select(...)",
1990
+ CAP_KEYS: 'Enter / Escape \u2192 .type("{enter}") / ("{esc}")',
1991
+ CAP_ROUTE: "Routenwechsel (SPA) \u2192 cy.url().should(...)",
1992
+ CAP_HTTP: "fetch / XHR \u2192 cy.intercept + cy.wait",
1993
+ SEC_ASSERT: "\u2705 Assertions",
1994
+ ASSERT_1: "Alt+Klick auf ein Element, um es zu pr\xFCfen, ohne seine Aktion auszul\xF6sen (Text, Wert, checked oder sichtbar).",
1995
+ ASSERT_2: "Oder nutze den Assertion-Builder im Befehle-Panel.",
1996
+ SEC_PANELS: "\u{1F5C2} Panels",
1997
+ PANEL_TESTS: "\u{1F4CB} Tests \u2014 gespeichert: nach Tag filtern, kopieren, kombinieren, exportieren.",
1998
+ PANEL_COMMANDS: "\u2328\uFE0F Befehle \u2014 aktuelle Aufzeichnung: umsortieren, l\xF6schen, Assertions hinzuf\xFCgen.",
1999
+ PANEL_CONFIG: "\u2699\uFE0F Config \u2014 Sprache, Selektor, HTTP, Cypress-Ordner, Login-Setup, Daten, Sichtbarkeit, Position.",
2000
+ PANEL_FILES: "\u{1F4C1} Dateien \u2014 Tests in deine .cy.ts einf\xFCgen und den Runner starten.",
2001
+ SEC_SELECTOR: "\u{1F50E} Selektoren",
2002
+ SELECTOR_1: "W\xE4hle das bevorzugte Attribut (data-cy, data-testid, aria-label, id) unter Config.",
2003
+ SELECTOR_2: "Hat ein Klick keinen zuverl\xE4ssigen Selektor, erscheint ein Picker zur Wahl des besten Vorfahren.",
2004
+ SEC_DATA: "\u{1F4BE} Daten",
2005
+ DATA_1: "Tests als JSON exportieren (alle / Auswahl / nach Tags).",
2006
+ DATA_2: "JSON importieren: wird zu deinen Daten hinzugef\xFCgt (nichts wird gel\xF6scht).",
2007
+ SEC_ADVANCED: "\u{1F680} Erweitert",
2008
+ ADV_INVISIBLE: "Unsichtbarer Modus: start-hidden + Ctrl+Shift+E, um in Produktion unauff\xE4llig aufzuzeichnen.",
2009
+ ADV_RUNNER: "Lokaler Runner: npx lib-e2e-cypress-runner, um einen Spec headless aus dem Editor zu starten.",
2010
+ ADV_CROSSAPP: "Cross-App: die Aufzeichnung \xFCbersteht den Wechsel des Micro-Frontends (gleicher Origin).",
2011
+ ADV_DRAG: "Ziehe den \u23FA-Button, um das Widget zu verschieben; die Position wird gemerkt.",
2012
+ ADV_LOGIN: "Login Setup (Ctrl+3): apunta a tu servicio de login; el grabador inyecta before()/beforeEach() autom\xE1ticamente en cada test nuevo.",
2013
+ // TODO: translate (de)
2014
+ CLOSE: "Schlie\xDFen",
2015
+ TAB_REFERENCE: "Kurzreferenz",
2016
+ TAB_GUIDE: "Nutzungsleitfaden",
2017
+ // TODO: translate (de) — usage guide body kept in Spanish for now.
2018
+ GUIDE_INTRO: "C\xF3mo sacarle partido al grabador, qu\xE9 cubre y qu\xE9 no.",
2019
+ G_SEC_WORKFLOW: "\u{1F9ED} Flujo de trabajo",
2020
+ G_WF_1: "1. Pulsa \u23FA (o Ctrl+R) para empezar a grabar.",
2021
+ G_WF_2: "2. Usa tu app como un usuario: clicks, formularios, navegaci\xF3n. Cada acci\xF3n se convierte en un comando Cypress.",
2022
+ G_WF_3: "3. A\xF1ade verificaciones con Alt+click sobre lo que quieras comprobar.",
2023
+ G_WF_4: "4. Pulsa \u23F9 para parar; ponle nombre y tags, y gu\xE1rdalo.",
2024
+ G_WF_5: "5. En \u{1F4C1} Ficheros, inserta el test en un .cy.ts o l\xE1nzalo con el runner local.",
2025
+ G_SEC_COVERED: "\u2705 Qu\xE9 cubre",
2026
+ G_COV_1: "Clicks, doble-click, click derecho, inputs de texto, checkbox/radio, select y teclas Enter/Escape.",
2027
+ G_COV_2: "Navegaci\xF3n SPA (pushState/replaceState/popstate) \u2192 cy.url().should(...).",
2028
+ G_COV_3: "Llamadas fetch/XHR (GET/POST/PUT) \u2192 cy.intercept + cy.wait, con validaci\xF3n de body opcional.",
2029
+ G_COV_4: "Selector fiable (data-cy/testid/aria/id) y picker cuando no hay uno claro.",
2030
+ G_COV_5: "Aserciones autom\xE1ticas (Alt+click) y constructor manual.",
2031
+ G_COV_6: "Continuidad al cambiar de micro-frontend (mismo origen), modo invisible e i18n.",
2032
+ G_COV_7: "Login Setup: configura tu funci\xF3n de login en Ctrl+3 \u2192 Login Setup y el grabador a\xF1ade los bloques before()/beforeEach() a cada test nuevo.",
2033
+ // TODO: translate (de)
2034
+ G_SEC_NOTCOVERED: "\u{1F6AB} Qu\xE9 NO cubre (por ahora)",
2035
+ G_NC_1: "Or\xEDgenes distintos / subdominios (solo mismo origen).",
2036
+ G_NC_2: "Subida de ficheros (selectFile), arrastrar y soltar, y hover.",
2037
+ G_NC_3: "La tecla Tab (Cypress no la soporta en .type()).",
2038
+ G_NC_4: "Peticiones DELETE (se ignoran a prop\xF3sito).",
2039
+ G_NC_5: "iframes y Shadow DOM de terceros pueden no capturarse."
2040
+ }
2041
+ };
2042
+
2043
+ // src/services/translation.service.ts
2044
+ var TranslationService = class {
2045
+ lang$;
2046
+ translations = {
2047
+ es: I18N_ES,
2048
+ en: I18N_EN,
2049
+ fr: I18N_FR,
2050
+ it: I18N_IT,
2051
+ de: I18N_DE
2052
+ };
2053
+ constructor() {
2054
+ this.lang$ = new Subject(this.detectLang());
2055
+ }
2056
+ /**
2057
+ * Sets the active language, notifying all subscribers.
2058
+ *
2059
+ * @param lang - One of the supported language codes (`'es'`, `'en'`, `'fr'`, `'it'`, `'de'`).
2060
+ */
2061
+ setLang(lang) {
2062
+ this.lang$.next(lang);
2063
+ }
2064
+ /** Returns the currently active language code. */
2065
+ getLang() {
2066
+ return this.lang$.getValue();
2067
+ }
2068
+ /** Subscribe to language changes; returns an unsubscribe function. */
2069
+ onLangChange(fn) {
2070
+ return this.lang$.subscribe(fn);
2071
+ }
2072
+ /**
2073
+ * Resolves a dot-separated translation key against the current language's
2074
+ * translation map. Returns the key itself when the path is not found, so
2075
+ * missing translations are visible rather than silent.
2076
+ *
2077
+ * @param key - A dot-separated path into the translation object
2078
+ * (e.g. `'RECORDER.START_BTN'`).
2079
+ * @returns The translated string, or `key` if the path does not exist.
2080
+ */
2081
+ translate(key) {
2082
+ const keys = key.split(".");
2083
+ let value = this.translations[this.lang$.getValue()];
2084
+ for (const k of keys) {
2085
+ value = value?.[k];
2086
+ if (value === void 0) return key;
2087
+ }
2088
+ return value;
2089
+ }
2090
+ /**
2091
+ * Detects the best initial language from `navigator.language`. Falls back to
2092
+ * `'es'` when the browser language is not one of the supported codes.
2093
+ *
2094
+ * @returns The detected or default {@link Lang} code.
2095
+ */
2096
+ detectLang() {
2097
+ const browserLang = navigator.language.split("-")[0];
2098
+ return isLang(browserLang) ? browserLang : "es";
2099
+ }
2100
+ };
2101
+ var translationService = new TranslationService();
2102
+
2103
+ // src/components/base.element.ts
2104
+ var BaseElement = class extends HTMLElement {
2105
+ /** Attached shadow root (open mode). Available from the constructor onwards. */
2106
+ shadow;
2107
+ /**
2108
+ * Translation service instance.
2109
+ * Defaults to the global singleton; override for isolated unit tests.
2110
+ */
2111
+ translation = translationService;
2112
+ constructor() {
2113
+ super();
2114
+ this.shadow = this.attachShadow({ mode: "open" });
2115
+ }
2116
+ /**
2117
+ * Returns the localised string for an i18n key.
2118
+ * Falls back to the raw key when the service is unavailable (e.g. in tests).
2119
+ *
2120
+ * @param key - Dot-separated translation key (e.g. `'PICKER.TITLE'`).
2121
+ * @returns Translated string, or the key itself if no translation is found.
2122
+ */
2123
+ t(key) {
2124
+ return this.translation?.translate(key) ?? key;
2125
+ }
2126
+ };
2127
+
2128
+ // src/components/selector-picker/selector-picker.ts
2129
+ var OWN_DATA_CY = "lib-e2e-cypress-for-dummys";
2130
+ var MAX_ANCESTORS = 10;
2131
+ var SelectorPickerElement = class extends BaseElement {
2132
+ targetElement = null;
2133
+ recording;
2134
+ ancestors = [];
2135
+ rows = [];
2136
+ selectedIndex = 0;
2137
+ keyHandler = null;
2138
+ unsubRecording = null;
2139
+ unsubPause = null;
2140
+ connectedCallback() {
2141
+ this.setAttribute("data-cy", "lib-e2e-cypress-for-dummys");
2142
+ this.ancestors = this.buildAncestors();
2143
+ this.rows = this.ancestors.map(describePickerRow);
2144
+ this.selectedIndex = this.findBestIndex();
2145
+ this.render();
2146
+ this.attachKeyListener();
2147
+ this.attachRowClickListeners();
2148
+ this.subscribeToRecordingChanges();
2149
+ }
2150
+ disconnectedCallback() {
2151
+ this.detachKeyListener();
2152
+ this.unsubRecording?.();
2153
+ this.unsubPause?.();
2154
+ }
2155
+ // ── Ancestor chain ──────────────────────────────────────────────────────────
2156
+ buildAncestors() {
2157
+ const chain = [];
2158
+ let current = this.targetElement;
2159
+ while (current && current.tagName.toLowerCase() !== "html" && chain.length < MAX_ANCESTORS) {
2160
+ if (current.getAttribute("data-cy") === OWN_DATA_CY) {
2161
+ current = current.parentElement;
2162
+ continue;
2163
+ }
2164
+ chain.push(current);
2165
+ current = current.parentElement;
2166
+ }
2167
+ return chain;
2168
+ }
2169
+ findBestIndex() {
2170
+ for (let i = 0; i < this.rows.length; i++) {
2171
+ const q = this.rows[i].quality;
2172
+ if (q === "excellent" || q === "good" || q === "acceptable") return i;
2173
+ }
2174
+ return 0;
2175
+ }
2176
+ // ── Rendering ───────────────────────────────────────────────────────────────
2177
+ render() {
2178
+ this.shadow.innerHTML = `<style>${SELECTOR_PICKER_STYLES}</style>${renderPicker(
2179
+ this.rows,
2180
+ this.selectedIndex,
2181
+ this.t.bind(this)
2182
+ )}`;
2183
+ }
2184
+ // ── Keyboard ────────────────────────────────────────────────────────────────
2185
+ attachKeyListener() {
2186
+ this.keyHandler = (e) => {
2187
+ if (e.key === "ArrowDown") {
2188
+ e.stopPropagation();
2189
+ e.preventDefault();
2190
+ this.selectedIndex = (this.selectedIndex + 1) % this.ancestors.length;
2191
+ this.render();
2192
+ this.attachRowClickListeners();
2193
+ } else if (e.key === "ArrowUp") {
2194
+ e.stopPropagation();
2195
+ e.preventDefault();
2196
+ this.selectedIndex = (this.selectedIndex - 1 + this.ancestors.length) % this.ancestors.length;
2197
+ this.render();
2198
+ this.attachRowClickListeners();
2199
+ } else if (e.key === "Enter") {
2200
+ e.stopPropagation();
2201
+ this.confirm(this.selectedIndex);
2202
+ } else if (e.key === "Escape") {
2203
+ e.stopPropagation();
2204
+ this.cancel();
2205
+ }
2206
+ };
2207
+ window.addEventListener("keydown", this.keyHandler, { capture: true });
2208
+ }
2209
+ detachKeyListener() {
2210
+ if (this.keyHandler) {
2211
+ window.removeEventListener("keydown", this.keyHandler, { capture: true });
2212
+ this.keyHandler = null;
2213
+ }
2214
+ }
2215
+ // ── Row click listeners ─────────────────────────────────────────────────────
2216
+ attachRowClickListeners() {
2217
+ this.shadow.querySelectorAll("[data-idx]").forEach((row) => {
2218
+ row.addEventListener("click", () => {
2219
+ const idx = parseInt(row.dataset["idx"] ?? "0", 10);
2220
+ this.confirm(idx);
2221
+ });
2222
+ });
2223
+ }
2224
+ // ── Recording auto-close ────────────────────────────────────────────────────
2225
+ subscribeToRecordingChanges() {
2226
+ this.unsubRecording = this.recording.onRecordingChange((isRecording) => {
2227
+ if (!isRecording) this.closeSilently();
2228
+ });
2229
+ this.unsubPause = this.recording.onPauseChange((isPaused) => {
2230
+ if (isPaused) this.closeSilently();
2231
+ });
2232
+ }
2233
+ // ── Actions ─────────────────────────────────────────────────────────────────
2234
+ confirm(index) {
2235
+ const row = this.rows[index];
2236
+ if (!row) return;
2237
+ const command = `cy.get('${escapeSingleQuotes(row.selector)}').click()`;
2238
+ this.recording.appendCommand(command);
2239
+ this.dispatchEvent(new CustomEvent("selectorchosen", { detail: command, bubbles: true, composed: true }));
2240
+ this.closeSilently();
2241
+ }
2242
+ cancel() {
2243
+ this.dispatchEvent(new CustomEvent("pickercancelled", { bubbles: true, composed: true }));
2244
+ this.closeSilently();
2245
+ }
2246
+ closeSilently() {
2247
+ this.detachKeyListener();
2248
+ this.unsubRecording?.();
2249
+ this.unsubPause?.();
2250
+ this.unsubRecording = null;
2251
+ this.unsubPause = null;
2252
+ this.remove();
2253
+ }
2254
+ };
2255
+ if (!customElements.get("lib-e2e-selector-picker")) {
2256
+ customElements.define("lib-e2e-selector-picker", SelectorPickerElement);
2257
+ }
2258
+
2259
+ export {
2260
+ SUPPORTED_LANGS,
2261
+ isLang,
2262
+ LOCALE_BY_LANG,
2263
+ localeForLang,
2264
+ Subject,
2265
+ TranslationService,
2266
+ escapeSingleQuotes,
2267
+ selectorLiteral,
2268
+ escapeCssAttrValue,
2269
+ normalizeBlock,
2270
+ FORBIDDEN_ID_PREFIXES,
2271
+ THEME,
2272
+ scrollbar,
2273
+ SCROLLBAR_INLINE,
2274
+ escHtml,
2275
+ escAttr,
2276
+ BaseElement,
2277
+ SelectorPickerElement
2278
+ };
2279
+ //# sourceMappingURL=chunk-PUZ6LLII.js.map