lib-e2e-cypress-for-dummys-ts 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -1
- package/dist/index.cjs +322 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +319 -59
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -92,7 +92,9 @@ var I18N_ES = {
|
|
|
92
92
|
NO_TAGS: "Sin etiquetas",
|
|
93
93
|
SAVE_BTN: "\u{1F4BE} Guardar",
|
|
94
94
|
SAVE_AND_EDIT: "\u{1F4DD} Guardar y editar",
|
|
95
|
-
REMOVE_TAG_TITLE: "Quitar"
|
|
95
|
+
REMOVE_TAG_TITLE: "Quitar",
|
|
96
|
+
NOTES_LABEL: "Descripci\xF3n / Notas (opcional):",
|
|
97
|
+
NOTES_PLACEHOLDER: "Qu\xE9 valida este test, condiciones previas, etc."
|
|
96
98
|
},
|
|
97
99
|
TEST_EDITOR: {
|
|
98
100
|
NO_TAGS: "Sin etiquetas",
|
|
@@ -141,7 +143,10 @@ var I18N_ES = {
|
|
|
141
143
|
JSON_BAD_FORMAT: "El archivo no tiene el formato esperado.",
|
|
142
144
|
SMART_SELECTOR_SECTION: "\u{1F50D} Selector inteligente",
|
|
143
145
|
SMART_SELECTOR_TITLE: "Selector inteligente",
|
|
144
|
-
SMART_SELECTOR_SUB: "Muestra un picker al hacer click en elementos sin selector v\xE1lido."
|
|
146
|
+
SMART_SELECTOR_SUB: "Muestra un picker al hacer click en elementos sin selector v\xE1lido.",
|
|
147
|
+
START_HIDDEN_SECTION: "\u{1F441} Visibilidad del widget",
|
|
148
|
+
START_HIDDEN_TITLE: "Iniciar oculto",
|
|
149
|
+
START_HIDDEN_SUB: "El widget arranca invisible. Usa Ctrl+Shift+E para mostrarlo u ocultarlo."
|
|
145
150
|
},
|
|
146
151
|
SELECTOR_PICKER: {
|
|
147
152
|
TITLE: "Selecciona un elemento del DOM",
|
|
@@ -254,7 +259,9 @@ var I18N_EN = {
|
|
|
254
259
|
NO_TAGS: "No tags",
|
|
255
260
|
SAVE_BTN: "\u{1F4BE} Save",
|
|
256
261
|
SAVE_AND_EDIT: "\u{1F4DD} Save and edit",
|
|
257
|
-
REMOVE_TAG_TITLE: "Remove"
|
|
262
|
+
REMOVE_TAG_TITLE: "Remove",
|
|
263
|
+
NOTES_LABEL: "Description / Notes (optional):",
|
|
264
|
+
NOTES_PLACEHOLDER: "What this test validates, preconditions, etc."
|
|
258
265
|
},
|
|
259
266
|
TEST_EDITOR: {
|
|
260
267
|
NO_TAGS: "No tags",
|
|
@@ -303,7 +310,10 @@ var I18N_EN = {
|
|
|
303
310
|
JSON_BAD_FORMAT: "The file does not have the expected format.",
|
|
304
311
|
SMART_SELECTOR_SECTION: "\u{1F50D} Smart selector",
|
|
305
312
|
SMART_SELECTOR_TITLE: "Smart selector",
|
|
306
|
-
SMART_SELECTOR_SUB: "Shows a picker when clicking elements with no valid selector."
|
|
313
|
+
SMART_SELECTOR_SUB: "Shows a picker when clicking elements with no valid selector.",
|
|
314
|
+
START_HIDDEN_SECTION: "\u{1F441} Widget visibility",
|
|
315
|
+
START_HIDDEN_TITLE: "Start hidden",
|
|
316
|
+
START_HIDDEN_SUB: "The widget starts invisible. Use Ctrl+Shift+E to show or hide it."
|
|
307
317
|
},
|
|
308
318
|
SELECTOR_PICKER: {
|
|
309
319
|
TITLE: "Select a DOM element",
|
|
@@ -416,7 +426,9 @@ var I18N_FR = {
|
|
|
416
426
|
NO_TAGS: "Sans \xE9tiquettes",
|
|
417
427
|
SAVE_BTN: "\u{1F4BE} Enregistrer",
|
|
418
428
|
SAVE_AND_EDIT: "\u{1F4DD} Enregistrer et \xE9diter",
|
|
419
|
-
REMOVE_TAG_TITLE: "Retirer"
|
|
429
|
+
REMOVE_TAG_TITLE: "Retirer",
|
|
430
|
+
NOTES_LABEL: "Description / Notes (optionnel) :",
|
|
431
|
+
NOTES_PLACEHOLDER: "Ce que ce test valide, conditions pr\xE9alables, etc."
|
|
420
432
|
},
|
|
421
433
|
TEST_EDITOR: {
|
|
422
434
|
NO_TAGS: "Sans \xE9tiquettes",
|
|
@@ -465,7 +477,10 @@ var I18N_FR = {
|
|
|
465
477
|
JSON_BAD_FORMAT: "Le fichier n'a pas le format attendu.",
|
|
466
478
|
SMART_SELECTOR_SECTION: "\u{1F50D} S\xE9lecteur intelligent",
|
|
467
479
|
SMART_SELECTOR_TITLE: "S\xE9lecteur intelligent",
|
|
468
|
-
SMART_SELECTOR_SUB: "Affiche un s\xE9lecteur lors du clic sur des \xE9l\xE9ments sans s\xE9lecteur valide."
|
|
480
|
+
SMART_SELECTOR_SUB: "Affiche un s\xE9lecteur lors du clic sur des \xE9l\xE9ments sans s\xE9lecteur valide.",
|
|
481
|
+
START_HIDDEN_SECTION: "\u{1F441} Visibilit\xE9 du widget",
|
|
482
|
+
START_HIDDEN_TITLE: "D\xE9marrer masqu\xE9",
|
|
483
|
+
START_HIDDEN_SUB: "Le widget d\xE9marre invisible. Utilisez Ctrl+Shift+E pour l'afficher ou le masquer."
|
|
469
484
|
},
|
|
470
485
|
SELECTOR_PICKER: {
|
|
471
486
|
TITLE: "S\xE9lectionnez un \xE9l\xE9ment du DOM",
|
|
@@ -578,7 +593,9 @@ var I18N_IT = {
|
|
|
578
593
|
NO_TAGS: "Nessuna etichetta",
|
|
579
594
|
SAVE_BTN: "\u{1F4BE} Salva",
|
|
580
595
|
SAVE_AND_EDIT: "\u{1F4DD} Salva e modifica",
|
|
581
|
-
REMOVE_TAG_TITLE: "Rimuovi"
|
|
596
|
+
REMOVE_TAG_TITLE: "Rimuovi",
|
|
597
|
+
NOTES_LABEL: "Descrizione / Note (opzionale):",
|
|
598
|
+
NOTES_PLACEHOLDER: "Cosa valida questo test, condizioni preliminari, ecc."
|
|
582
599
|
},
|
|
583
600
|
TEST_EDITOR: {
|
|
584
601
|
NO_TAGS: "Nessuna etichetta",
|
|
@@ -627,7 +644,10 @@ var I18N_IT = {
|
|
|
627
644
|
JSON_BAD_FORMAT: "Il file non ha il formato previsto.",
|
|
628
645
|
SMART_SELECTOR_SECTION: "\u{1F50D} Selettore intelligente",
|
|
629
646
|
SMART_SELECTOR_TITLE: "Selettore intelligente",
|
|
630
|
-
SMART_SELECTOR_SUB: "Mostra un selettore quando si fa clic su elementi senza selettore valido."
|
|
647
|
+
SMART_SELECTOR_SUB: "Mostra un selettore quando si fa clic su elementi senza selettore valido.",
|
|
648
|
+
START_HIDDEN_SECTION: "\u{1F441} Visibilit\xE0 del widget",
|
|
649
|
+
START_HIDDEN_TITLE: "Avvia nascosto",
|
|
650
|
+
START_HIDDEN_SUB: "Il widget si avvia invisibile. Usa Ctrl+Shift+E per mostrarlo o nasconderlo."
|
|
631
651
|
},
|
|
632
652
|
SELECTOR_PICKER: {
|
|
633
653
|
TITLE: "Seleziona un elemento DOM",
|
|
@@ -740,7 +760,9 @@ var I18N_DE = {
|
|
|
740
760
|
NO_TAGS: "Keine Tags",
|
|
741
761
|
SAVE_BTN: "\u{1F4BE} Speichern",
|
|
742
762
|
SAVE_AND_EDIT: "\u{1F4DD} Speichern und bearbeiten",
|
|
743
|
-
REMOVE_TAG_TITLE: "Entfernen"
|
|
763
|
+
REMOVE_TAG_TITLE: "Entfernen",
|
|
764
|
+
NOTES_LABEL: "Beschreibung / Notizen (optional):",
|
|
765
|
+
NOTES_PLACEHOLDER: "Was dieser Test validiert, Voraussetzungen usw."
|
|
744
766
|
},
|
|
745
767
|
TEST_EDITOR: {
|
|
746
768
|
NO_TAGS: "Keine Tags",
|
|
@@ -789,7 +811,10 @@ var I18N_DE = {
|
|
|
789
811
|
JSON_BAD_FORMAT: "Die Datei hat nicht das erwartete Format.",
|
|
790
812
|
SMART_SELECTOR_SECTION: "\u{1F50D} Intelligenter Selektor",
|
|
791
813
|
SMART_SELECTOR_TITLE: "Intelligenter Selektor",
|
|
792
|
-
SMART_SELECTOR_SUB: "Zeigt ein Auswahlfeld, wenn auf Elemente ohne g\xFCltigen Selektor geklickt wird."
|
|
814
|
+
SMART_SELECTOR_SUB: "Zeigt ein Auswahlfeld, wenn auf Elemente ohne g\xFCltigen Selektor geklickt wird.",
|
|
815
|
+
START_HIDDEN_SECTION: "\u{1F441} Widget-Sichtbarkeit",
|
|
816
|
+
START_HIDDEN_TITLE: "Versteckt starten",
|
|
817
|
+
START_HIDDEN_SUB: "Das Widget startet unsichtbar. Verwenden Sie Ctrl+Shift+E zum Ein-/Ausblenden."
|
|
793
818
|
},
|
|
794
819
|
SELECTOR_PICKER: {
|
|
795
820
|
TITLE: "DOM-Element ausw\xE4hlen",
|
|
@@ -915,13 +940,37 @@ var TranslationService = class {
|
|
|
915
940
|
};
|
|
916
941
|
var translationService = new TranslationService();
|
|
917
942
|
|
|
943
|
+
// src/utils/code-format.utils.ts
|
|
944
|
+
function gcd(a, b) {
|
|
945
|
+
while (b) {
|
|
946
|
+
const t = b;
|
|
947
|
+
b = a % b;
|
|
948
|
+
a = t;
|
|
949
|
+
}
|
|
950
|
+
return a;
|
|
951
|
+
}
|
|
952
|
+
function normalizeBlock(code, baseIndent) {
|
|
953
|
+
const lines = code.split("\n").map((l) => l.trimEnd());
|
|
954
|
+
const nonEmpty = lines.filter((l) => l.trim().length > 0);
|
|
955
|
+
if (!nonEmpty.length) return "";
|
|
956
|
+
const indents = nonEmpty.map((l) => l.length - l.trimStart().length);
|
|
957
|
+
const minIndent = Math.min(...indents);
|
|
958
|
+
const relIndents = [...new Set(indents.map((n) => n - minIndent).filter((n) => n > 0))];
|
|
959
|
+
const step = relIndents.length > 0 ? relIndents.reduce(gcd) : 2;
|
|
960
|
+
return lines.map((l) => {
|
|
961
|
+
if (!l.trim()) return "";
|
|
962
|
+
const level = Math.round((l.length - l.trimStart().length - minIndent) / step);
|
|
963
|
+
return baseIndent + " ".repeat(level) + l.trimStart();
|
|
964
|
+
}).join("\n");
|
|
965
|
+
}
|
|
966
|
+
|
|
918
967
|
// src/services/transformation.service.ts
|
|
919
968
|
var TransformationService = class {
|
|
920
969
|
toLang(lang) {
|
|
921
970
|
return isLang(lang) ? lang : "en";
|
|
922
971
|
}
|
|
923
972
|
generateItDescription(description, commands) {
|
|
924
|
-
const commandsBlock = commands.map((cmd) =>
|
|
973
|
+
const commandsBlock = commands.map((cmd) => normalizeBlock(cmd, " ")).join("\n");
|
|
925
974
|
return `it('${description}', () => {
|
|
926
975
|
${commandsBlock}
|
|
927
976
|
});`;
|
|
@@ -952,6 +1001,13 @@ ${interceptors} })
|
|
|
952
1001
|
}
|
|
953
1002
|
return content.slice(0, idx) + "\n" + itBlock + "\n" + content.slice(idx);
|
|
954
1003
|
}
|
|
1004
|
+
buildBlockComment(notes) {
|
|
1005
|
+
if (!notes.trim()) return "";
|
|
1006
|
+
const lines = notes.split("\n").map((l) => ` * ${l}`).join("\n");
|
|
1007
|
+
return `/**
|
|
1008
|
+
${lines}
|
|
1009
|
+
*/`;
|
|
1010
|
+
}
|
|
955
1011
|
isFile(file) {
|
|
956
1012
|
return !!file && file.kind === "file";
|
|
957
1013
|
}
|
|
@@ -1362,9 +1418,9 @@ var PersistenceService = class {
|
|
|
1362
1418
|
return this._db;
|
|
1363
1419
|
}
|
|
1364
1420
|
// ── Tests ─────────────────────────────────────────────────────────────────
|
|
1365
|
-
async insertTest(name, commands = [], interceptors = [], tags = []) {
|
|
1421
|
+
async insertTest(name, commands = [], interceptors = [], tags = [], notes) {
|
|
1366
1422
|
const db = await this.getDB();
|
|
1367
|
-
const record = { name, createdAt: Date.now(), ...tags.length ? { tags } : {} };
|
|
1423
|
+
const record = { name, createdAt: Date.now(), ...tags.length ? { tags } : {}, ...notes ? { notes } : {} };
|
|
1368
1424
|
const id = await db.add("tests", record);
|
|
1369
1425
|
if (commands.length) await this.insertCommands(commands, id);
|
|
1370
1426
|
if (interceptors.length) await this.insertInterceptors(interceptors, id);
|
|
@@ -1388,9 +1444,9 @@ var PersistenceService = class {
|
|
|
1388
1444
|
const commands = await this.getCommandStrings(testId);
|
|
1389
1445
|
const interceptors = await this.getInterceptorStrings(testId);
|
|
1390
1446
|
const itBlock = `it('${record.name}', () => {
|
|
1391
|
-
|
|
1447
|
+
${commands.map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
1392
1448
|
});`;
|
|
1393
|
-
const interceptorsBlock = interceptors.length ? " // Auto-generated Cypress interceptors\n" + interceptors.map((i) => " "
|
|
1449
|
+
const interceptorsBlock = interceptors.length ? " // Auto-generated Cypress interceptors\n" + interceptors.map((i) => normalizeBlock(i, " ")).join("\n") + "\n" : "";
|
|
1394
1450
|
return { ...record, commands, interceptors, cypressCommands: commands, itBlock, interceptorsBlock };
|
|
1395
1451
|
}
|
|
1396
1452
|
async deleteTest(id) {
|
|
@@ -2129,7 +2185,8 @@ if (!customElements.get("test-previsualizer")) {
|
|
|
2129
2185
|
var SAVE_TEST_STYLES = `
|
|
2130
2186
|
:host { display: block; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: #e6edf3; }
|
|
2131
2187
|
* { box-sizing: border-box; }
|
|
2132
|
-
.container { padding: 24px 28px; text-align:
|
|
2188
|
+
.container { padding: 24px 28px; text-align: left; }
|
|
2189
|
+
.btn-row, p { text-align: center; }
|
|
2133
2190
|
p { margin: 0 0 20px; font-size: 14px; color: #8b949e; line-height: 1.5; }
|
|
2134
2191
|
.btn-row { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-top: 16px; }
|
|
2135
2192
|
button {
|
|
@@ -2151,6 +2208,15 @@ var SAVE_TEST_STYLES = `
|
|
|
2151
2208
|
}
|
|
2152
2209
|
input[type="text"]:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.15); }
|
|
2153
2210
|
input[type="text"]::placeholder { color: #484f58; }
|
|
2211
|
+
textarea {
|
|
2212
|
+
width: 100%; padding: 10px 14px; border: 1px solid #30363d;
|
|
2213
|
+
border-radius: 8px; background: #0d1117; color: #e6edf3;
|
|
2214
|
+
font-size: 14px; outline: none; margin-bottom: 4px;
|
|
2215
|
+
font-family: inherit; resize: vertical; line-height: 1.5;
|
|
2216
|
+
transition: border-color 0.15s, box-shadow 0.15s;
|
|
2217
|
+
}
|
|
2218
|
+
textarea:focus { border-color: #2f81f7; box-shadow: 0 0 0 3px rgba(47,129,247,0.15); }
|
|
2219
|
+
textarea::placeholder { color: #484f58; }
|
|
2154
2220
|
.tag-label {
|
|
2155
2221
|
font-size: 11px; color: #484f58; text-align: left; margin-bottom: 5px; display: block;
|
|
2156
2222
|
}
|
|
@@ -2189,7 +2255,7 @@ function renderSaveTestAsk(t) {
|
|
|
2189
2255
|
</div>
|
|
2190
2256
|
</div>`;
|
|
2191
2257
|
}
|
|
2192
|
-
function renderSaveTestDesc(description, tags, t) {
|
|
2258
|
+
function renderSaveTestDesc(description, notes, tags, t) {
|
|
2193
2259
|
const chipsHtml = tags.map(
|
|
2194
2260
|
(tag) => `<span class="chip">${escHtml(tag)}<button class="chip-del" data-tag="${escAttr(tag)}" title="${t("SAVE_TEST.REMOVE_TAG_TITLE")}">\u2715</button></span>`
|
|
2195
2261
|
).join("");
|
|
@@ -2198,6 +2264,8 @@ function renderSaveTestDesc(description, tags, t) {
|
|
|
2198
2264
|
<p>${t("SAVE_TEST.DESC_LABEL")} (<code>it()</code>):</p>
|
|
2199
2265
|
<input id="desc-input" type="text" placeholder="${t("SAVE_TEST.DESC_PLACEHOLDER")}"
|
|
2200
2266
|
value="${escAttr(description)}" autocomplete="off" />
|
|
2267
|
+
<span class="tag-label">${t("SAVE_TEST.NOTES_LABEL")}</span>
|
|
2268
|
+
<textarea id="notes-input" rows="3" placeholder="${escAttr(t("SAVE_TEST.NOTES_PLACEHOLDER"))}">${escHtml(notes)}</textarea>
|
|
2201
2269
|
<span class="tag-label">${t("SAVE_TEST.TAGS_LABEL")}</span>
|
|
2202
2270
|
<div class="tag-input-row">
|
|
2203
2271
|
<input id="tag-input" type="text" placeholder="${t("SAVE_TEST.TAGS_PLACEHOLDER")}" autocomplete="off" />
|
|
@@ -2217,6 +2285,7 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
2217
2285
|
shadow;
|
|
2218
2286
|
_step = "ask";
|
|
2219
2287
|
description = "";
|
|
2288
|
+
notes = "";
|
|
2220
2289
|
tags = [];
|
|
2221
2290
|
translation = translationService;
|
|
2222
2291
|
constructor() {
|
|
@@ -2234,17 +2303,18 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
2234
2303
|
this.render();
|
|
2235
2304
|
}
|
|
2236
2305
|
confirmSave() {
|
|
2237
|
-
this.dispatch("savetest", { description: this.description.trim(), tags: [...this.tags] });
|
|
2306
|
+
this.dispatch("savetest", { description: this.description.trim(), notes: this.notes, tags: [...this.tags] });
|
|
2238
2307
|
}
|
|
2239
2308
|
confirmSaveAndExport() {
|
|
2240
|
-
this.dispatch("saveandexport", { description: this.description.trim(), tags: [...this.tags] });
|
|
2309
|
+
this.dispatch("saveandexport", { description: this.description.trim(), notes: this.notes, tags: [...this.tags] });
|
|
2241
2310
|
}
|
|
2242
2311
|
cancel() {
|
|
2243
|
-
this.dispatch("savetest", { description: null, tags: [] });
|
|
2312
|
+
this.dispatch("savetest", { description: null, notes: "", tags: [] });
|
|
2244
2313
|
}
|
|
2245
2314
|
restartComponent() {
|
|
2246
2315
|
this._step = "ask";
|
|
2247
2316
|
this.description = "";
|
|
2317
|
+
this.notes = "";
|
|
2248
2318
|
this.tags = [];
|
|
2249
2319
|
this.render();
|
|
2250
2320
|
}
|
|
@@ -2271,12 +2341,16 @@ var SaveTestElement = class extends HTMLElement {
|
|
|
2271
2341
|
this.shadow.getElementById("btn-yes")?.addEventListener("click", () => this.askSave());
|
|
2272
2342
|
this.shadow.getElementById("btn-no")?.addEventListener("click", () => this.cancel());
|
|
2273
2343
|
} else {
|
|
2274
|
-
this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestDesc(this.description, this.tags, this.t.bind(this))}`;
|
|
2344
|
+
this.shadow.innerHTML = `<style>${SAVE_TEST_STYLES}</style>${renderSaveTestDesc(this.description, this.notes, this.tags, this.t.bind(this))}`;
|
|
2275
2345
|
const descInput = this.shadow.getElementById("desc-input");
|
|
2346
|
+
const notesInput = this.shadow.getElementById("notes-input");
|
|
2276
2347
|
const tagInput = this.shadow.getElementById("tag-input");
|
|
2277
2348
|
descInput.addEventListener("input", () => {
|
|
2278
2349
|
this.description = descInput.value;
|
|
2279
2350
|
});
|
|
2351
|
+
notesInput.addEventListener("input", () => {
|
|
2352
|
+
this.notes = notesInput.value;
|
|
2353
|
+
});
|
|
2280
2354
|
const tryAddTag = () => {
|
|
2281
2355
|
this.addTag(tagInput.value);
|
|
2282
2356
|
tagInput.value = "";
|
|
@@ -2382,15 +2456,124 @@ var TEST_EDITOR_STYLES = `
|
|
|
2382
2456
|
background: #0d1117; padding: 10px 14px;
|
|
2383
2457
|
border-top: 1px solid #21262d;
|
|
2384
2458
|
}
|
|
2385
|
-
.
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
.
|
|
2459
|
+
.test-notes {
|
|
2460
|
+
margin: 0 0 10px; padding: 8px 12px;
|
|
2461
|
+
background: rgba(47,129,247,0.06); border-left: 3px solid rgba(47,129,247,0.4);
|
|
2462
|
+
border-radius: 0 6px 6px 0; font-size: 12px; color: #8b949e;
|
|
2463
|
+
line-height: 1.6; white-space: pre-wrap; word-break: break-word;
|
|
2464
|
+
}
|
|
2465
|
+
.code-preview {
|
|
2466
|
+
margin: 0; padding: 10px 12px; background: #161b22;
|
|
2467
|
+
border-radius: 6px; border: 1px solid #21262d;
|
|
2468
|
+
font-size: 11px; color: #c9d1d9; line-height: 1.7;
|
|
2469
|
+
font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
|
|
2470
|
+
overflow-x: auto; white-space: pre;
|
|
2471
|
+
scrollbar-width: thin; scrollbar-color: #30363d transparent;
|
|
2472
|
+
}
|
|
2473
|
+
.code-preview::-webkit-scrollbar { height: 4px; }
|
|
2474
|
+
.code-preview::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }
|
|
2475
|
+
.code-preview-icp { margin-top: 8px; }
|
|
2476
|
+
.sh-kw { color: #ff7b72; }
|
|
2477
|
+
.sh-bi { color: #d2a8ff; }
|
|
2478
|
+
.sh-str { color: #a5d6ff; }
|
|
2479
|
+
.sh-cmt { color: #8b949e; font-style: italic; }
|
|
2480
|
+
.sh-num { color: #79c0ff; }
|
|
2392
2481
|
`;
|
|
2393
2482
|
|
|
2483
|
+
// src/utils/syntax-highlight.utils.ts
|
|
2484
|
+
var KEYWORDS = /* @__PURE__ */ new Set([
|
|
2485
|
+
"describe",
|
|
2486
|
+
"it",
|
|
2487
|
+
"xit",
|
|
2488
|
+
"fit",
|
|
2489
|
+
"xdescribe",
|
|
2490
|
+
"fdescribe",
|
|
2491
|
+
"beforeEach",
|
|
2492
|
+
"afterEach",
|
|
2493
|
+
"before",
|
|
2494
|
+
"after",
|
|
2495
|
+
"context",
|
|
2496
|
+
"const",
|
|
2497
|
+
"let",
|
|
2498
|
+
"var",
|
|
2499
|
+
"function",
|
|
2500
|
+
"return",
|
|
2501
|
+
"if",
|
|
2502
|
+
"else",
|
|
2503
|
+
"import",
|
|
2504
|
+
"export",
|
|
2505
|
+
"from",
|
|
2506
|
+
"new",
|
|
2507
|
+
"this",
|
|
2508
|
+
"null",
|
|
2509
|
+
"undefined",
|
|
2510
|
+
"true",
|
|
2511
|
+
"false",
|
|
2512
|
+
"async",
|
|
2513
|
+
"await",
|
|
2514
|
+
"of",
|
|
2515
|
+
"in",
|
|
2516
|
+
"typeof",
|
|
2517
|
+
"void"
|
|
2518
|
+
]);
|
|
2519
|
+
var BUILTINS = /* @__PURE__ */ new Set(["cy", "expect", "assert", "Cypress", "chai"]);
|
|
2520
|
+
function syntaxHighlight(code) {
|
|
2521
|
+
return code.split("\n").map(highlightLine).join("\n");
|
|
2522
|
+
}
|
|
2523
|
+
function highlightLine(line) {
|
|
2524
|
+
let result = "";
|
|
2525
|
+
let i = 0;
|
|
2526
|
+
const len = line.length;
|
|
2527
|
+
while (i < len) {
|
|
2528
|
+
if (line[i] === "/" && i + 1 < len && line[i + 1] === "/") {
|
|
2529
|
+
result += `<span class="sh-cmt">${escHtml(line.slice(i))}</span>`;
|
|
2530
|
+
return result;
|
|
2531
|
+
}
|
|
2532
|
+
const q = line[i];
|
|
2533
|
+
if (q === "'" || q === '"' || q === "`") {
|
|
2534
|
+
let j = i + 1;
|
|
2535
|
+
while (j < len) {
|
|
2536
|
+
if (line[j] === "\\") {
|
|
2537
|
+
j += 2;
|
|
2538
|
+
continue;
|
|
2539
|
+
}
|
|
2540
|
+
if (line[j] === q) {
|
|
2541
|
+
j++;
|
|
2542
|
+
break;
|
|
2543
|
+
}
|
|
2544
|
+
j++;
|
|
2545
|
+
}
|
|
2546
|
+
result += `<span class="sh-str">${escHtml(line.slice(i, j))}</span>`;
|
|
2547
|
+
i = j;
|
|
2548
|
+
continue;
|
|
2549
|
+
}
|
|
2550
|
+
if (/[0-9]/.test(line[i]) && (i === 0 || !/[a-zA-Z_$]/.test(line[i - 1]))) {
|
|
2551
|
+
let j = i;
|
|
2552
|
+
while (j < len && /[0-9.]/.test(line[j])) j++;
|
|
2553
|
+
result += `<span class="sh-num">${escHtml(line.slice(i, j))}</span>`;
|
|
2554
|
+
i = j;
|
|
2555
|
+
continue;
|
|
2556
|
+
}
|
|
2557
|
+
if (/[a-zA-Z_$]/.test(line[i])) {
|
|
2558
|
+
let j = i;
|
|
2559
|
+
while (j < len && /[a-zA-Z0-9_$]/.test(line[j])) j++;
|
|
2560
|
+
const word = line.slice(i, j);
|
|
2561
|
+
if (KEYWORDS.has(word)) {
|
|
2562
|
+
result += `<span class="sh-kw">${escHtml(word)}</span>`;
|
|
2563
|
+
} else if (BUILTINS.has(word)) {
|
|
2564
|
+
result += `<span class="sh-bi">${escHtml(word)}</span>`;
|
|
2565
|
+
} else {
|
|
2566
|
+
result += escHtml(word);
|
|
2567
|
+
}
|
|
2568
|
+
i = j;
|
|
2569
|
+
continue;
|
|
2570
|
+
}
|
|
2571
|
+
result += escHtml(line[i]);
|
|
2572
|
+
i++;
|
|
2573
|
+
}
|
|
2574
|
+
return result;
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2394
2577
|
// src/components/test-editor/test-editor.template.ts
|
|
2395
2578
|
function renderTestEditor(state, t) {
|
|
2396
2579
|
const { tags, visible, selectedVisible, activeTag, selectMode, selectedIds, describeName, expandedIndex, interceptorsByTest } = state;
|
|
@@ -2408,18 +2591,20 @@ function renderTestEditor(state, t) {
|
|
|
2408
2591
|
const icps = interceptorsByTest[test.id] ?? test.interceptors ?? [];
|
|
2409
2592
|
const tagsHtml = (test.tags ?? []).length ? `<span class="test-tags">${(test.tags ?? []).map((tag) => `<span class="test-tag">${escHtml(tag)}</span>`).join("")}</span>` : "";
|
|
2410
2593
|
const checkbox = selectMode ? `<input type="checkbox" ${selectedIds.has(test.id) ? "checked" : ""} data-select="${test.id}" />` : "";
|
|
2594
|
+
const hasIcps = (test.interceptors ?? []).length > 0;
|
|
2595
|
+
const itBlockCode = `it('${test.name}', () => {
|
|
2596
|
+
${(test.commands ?? []).map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
2597
|
+
});`;
|
|
2598
|
+
const icpBlockCode = icps.length ? `beforeEach(() => {
|
|
2599
|
+
// Auto-generated Cypress interceptors
|
|
2600
|
+
${icps.map((c) => normalizeBlock(c, " ")).join("\n")}
|
|
2601
|
+
});` : "";
|
|
2602
|
+
const notesHtml = expanded && test.notes ? `<p class="test-notes">${escHtml(test.notes)}</p>` : "";
|
|
2411
2603
|
const body = expanded ? `
|
|
2412
2604
|
<div class="row-body">
|
|
2413
|
-
|
|
2414
|
-
<
|
|
2415
|
-
${
|
|
2416
|
-
<div class="section-title" style="margin-top:8px">${t("TEST_EDITOR.SECTION_INTERCEPTORS")}</div>
|
|
2417
|
-
${icps.map(escHtml).join("<br>")}
|
|
2418
|
-
</div>` : ""}
|
|
2419
|
-
<div class="copy-row">
|
|
2420
|
-
<button class="btn-icon" data-action="copy-cmds" data-idx="${i}">${t("TEST_EDITOR.COPY_CMDS_BTN")}</button>
|
|
2421
|
-
${icps.length ? `<button class="btn-icon" data-action="copy-icps" data-idx="${i}">${t("TEST_EDITOR.COPY_ICPS_BTN")}</button>` : ""}
|
|
2422
|
-
</div>
|
|
2605
|
+
${notesHtml}
|
|
2606
|
+
<pre class="code-preview">${syntaxHighlight(itBlockCode)}</pre>
|
|
2607
|
+
${icpBlockCode ? `<pre class="code-preview code-preview-icp">${syntaxHighlight(icpBlockCode)}</pre>` : ""}
|
|
2423
2608
|
</div>` : "";
|
|
2424
2609
|
return `
|
|
2425
2610
|
<div class="row${selectedIds.has(test.id) ? " selected-row" : ""}">
|
|
@@ -2428,6 +2613,8 @@ function renderTestEditor(state, t) {
|
|
|
2428
2613
|
<span class="test-name">${escHtml(test.name)}</span>
|
|
2429
2614
|
${tagsHtml}
|
|
2430
2615
|
<span class="test-date">${date}</span>
|
|
2616
|
+
<button class="btn-icon" data-action="copy-cmds" data-idx="${i}" title="${t("TEST_EDITOR.COPY_CMDS_BTN")}">${t("TEST_EDITOR.COPY_CMDS_BTN")}</button>
|
|
2617
|
+
${hasIcps ? `<button class="btn-icon" data-action="copy-icps" data-idx="${i}" title="${t("TEST_EDITOR.COPY_ICPS_BTN")}">${t("TEST_EDITOR.COPY_ICPS_BTN")}</button>` : ""}
|
|
2431
2618
|
<button class="btn-icon btn-del" data-action="delete" data-id="${test.id}" title="${t("TEST_EDITOR.DELETE_TITLE")}">\u{1F5D1}</button>
|
|
2432
2619
|
</div>
|
|
2433
2620
|
${body}
|
|
@@ -2606,7 +2793,7 @@ ${beforeEach}${itBlocks}
|
|
|
2606
2793
|
ev.stopPropagation();
|
|
2607
2794
|
const idx = Number(el.dataset["idx"]);
|
|
2608
2795
|
const t = visible[idx];
|
|
2609
|
-
this.copyToClipboard((this.interceptorsByTest[t?.id] ?? []).join("\n"));
|
|
2796
|
+
this.copyToClipboard((this.interceptorsByTest[t?.id] ?? t?.interceptors ?? []).join("\n"));
|
|
2610
2797
|
});
|
|
2611
2798
|
});
|
|
2612
2799
|
}
|
|
@@ -2719,7 +2906,7 @@ var LANGS = [
|
|
|
2719
2906
|
{ value: "de", label: "Deutsch" }
|
|
2720
2907
|
];
|
|
2721
2908
|
function renderConfiguration(state, t) {
|
|
2722
|
-
const { selectedLanguage, advancedHttpConfig, selectorStrategy, filesystemGranted, cypressFolderName, smartSelectorEnabled } = state;
|
|
2909
|
+
const { selectedLanguage, advancedHttpConfig, selectorStrategy, filesystemGranted, cypressFolderName, smartSelectorEnabled, startHidden } = state;
|
|
2723
2910
|
const langOptions = LANGS.map(
|
|
2724
2911
|
(l) => `<option value="${l.value}" ${selectedLanguage === l.value ? "selected" : ""}>${l.label}</option>`
|
|
2725
2912
|
).join("");
|
|
@@ -2759,6 +2946,18 @@ function renderConfiguration(state, t) {
|
|
|
2759
2946
|
</label>
|
|
2760
2947
|
</div>
|
|
2761
2948
|
|
|
2949
|
+
<!-- Start Hidden -->
|
|
2950
|
+
<div class="card">
|
|
2951
|
+
<div class="card-hd">${t("CONFIG.START_HIDDEN_SECTION")}</div>
|
|
2952
|
+
<label class="check-row">
|
|
2953
|
+
<input type="checkbox" id="start-hidden-toggle" ${startHidden ? "checked" : ""} />
|
|
2954
|
+
<div>
|
|
2955
|
+
<div class="check-title">${t("CONFIG.START_HIDDEN_TITLE")}</div>
|
|
2956
|
+
<div class="check-sub">${t("CONFIG.START_HIDDEN_SUB")}</div>
|
|
2957
|
+
</div>
|
|
2958
|
+
</label>
|
|
2959
|
+
</div>
|
|
2960
|
+
|
|
2762
2961
|
<!-- Selector Strategy -->
|
|
2763
2962
|
<div class="card card-wide">
|
|
2764
2963
|
<div class="card-hd">${t("CONFIG.SELECTOR_SECTION")}</div>
|
|
@@ -2821,6 +3020,7 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
2821
3020
|
advancedHttpConfig = false;
|
|
2822
3021
|
selectorStrategy = "data-cy";
|
|
2823
3022
|
smartSelectorEnabled = true;
|
|
3023
|
+
startHidden = false;
|
|
2824
3024
|
filesystemGranted = false;
|
|
2825
3025
|
cypressFolderName = null;
|
|
2826
3026
|
constructor() {
|
|
@@ -2846,6 +3046,7 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
2846
3046
|
this.advancedHttpConfig = localStorage.getItem("extendedHttpCommands") === "true";
|
|
2847
3047
|
this.selectorStrategy = config?.["selectorStrategy"] ?? "data-cy";
|
|
2848
3048
|
this.smartSelectorEnabled = config?.["smartSelectorEnabled"] !== "false";
|
|
3049
|
+
this.startHidden = config?.["startHidden"] === "true";
|
|
2849
3050
|
this.filesystemGranted = config?.["allowReadWriteFiles"] === "true";
|
|
2850
3051
|
const handle = config?.["cypressDirectoryHandle"];
|
|
2851
3052
|
this.cypressFolderName = handle?.name ?? null;
|
|
@@ -2863,6 +3064,12 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
2863
3064
|
this.persistence.setConfig({ extendedHttpCommands: checked ? "true" : "false" });
|
|
2864
3065
|
this.render();
|
|
2865
3066
|
}
|
|
3067
|
+
async onStartHiddenChange(checked) {
|
|
3068
|
+
this.startHidden = checked;
|
|
3069
|
+
await this.persistence.setConfig({ startHidden: checked ? "true" : "false" });
|
|
3070
|
+
this.dispatchEvent(new CustomEvent("starthiddenchange", { detail: checked, bubbles: true, composed: true }));
|
|
3071
|
+
this.render();
|
|
3072
|
+
}
|
|
2866
3073
|
async onSmartSelectorChange(enabled) {
|
|
2867
3074
|
this.smartSelectorEnabled = enabled;
|
|
2868
3075
|
await this.persistence.setConfig({ smartSelectorEnabled: enabled ? "true" : "false" });
|
|
@@ -2923,7 +3130,8 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
2923
3130
|
selectorStrategy: this.selectorStrategy,
|
|
2924
3131
|
filesystemGranted: this.filesystemGranted,
|
|
2925
3132
|
cypressFolderName: this.cypressFolderName,
|
|
2926
|
-
smartSelectorEnabled: this.smartSelectorEnabled
|
|
3133
|
+
smartSelectorEnabled: this.smartSelectorEnabled,
|
|
3134
|
+
startHidden: this.startHidden
|
|
2927
3135
|
}, this.t.bind(this))}`;
|
|
2928
3136
|
;
|
|
2929
3137
|
this.shadow.getElementById("lang-select").addEventListener(
|
|
@@ -2938,6 +3146,10 @@ var ConfigurationElement = class extends HTMLElement {
|
|
|
2938
3146
|
"change",
|
|
2939
3147
|
(e) => this.onSmartSelectorChange(e.target.checked)
|
|
2940
3148
|
);
|
|
3149
|
+
this.shadow.getElementById("start-hidden-toggle").addEventListener(
|
|
3150
|
+
"change",
|
|
3151
|
+
(e) => this.onStartHiddenChange(e.target.checked)
|
|
3152
|
+
);
|
|
2941
3153
|
this.shadow.getElementById("selector-strategy").addEventListener(
|
|
2942
3154
|
"change",
|
|
2943
3155
|
(e) => this.onSelectorStrategyChange(e.target.value)
|
|
@@ -3010,12 +3222,21 @@ var ADVANCED_TEST_EDITOR_STYLES = `
|
|
|
3010
3222
|
.file-name { font-size: 11px; color: #484f58; margin-bottom: 8px; font-family: monospace; }
|
|
3011
3223
|
pre {
|
|
3012
3224
|
background: #0d1117; padding: 12px; border-radius: 8px;
|
|
3013
|
-
font-size: 11px; color: #c9d1d9;
|
|
3014
|
-
white-space: pre-wrap; word-break: break-all; margin: 0;
|
|
3225
|
+
font-size: 11px; color: #c9d1d9; margin: 0;
|
|
3015
3226
|
font-family: 'Cascadia Code', 'Fira Code', 'Consolas', monospace;
|
|
3016
|
-
line-height: 1.7;
|
|
3017
|
-
|
|
3227
|
+
line-height: 1.7; border: 1px solid #21262d;
|
|
3228
|
+
white-space: pre; overflow-x: auto; overflow-y: auto;
|
|
3229
|
+
scrollbar-width: thin; scrollbar-color: #30363d transparent;
|
|
3018
3230
|
}
|
|
3231
|
+
pre::-webkit-scrollbar { width: 4px; height: 4px; }
|
|
3232
|
+
pre::-webkit-scrollbar-thumb { background: #30363d; border-radius: 2px; }
|
|
3233
|
+
.pre-block { font-size: 10.5px; }
|
|
3234
|
+
.pre-icp .sh-str { color: #85e89d; }
|
|
3235
|
+
.sh-kw { color: #ff7b72; }
|
|
3236
|
+
.sh-bi { color: #d2a8ff; }
|
|
3237
|
+
.sh-str { color: #a5d6ff; }
|
|
3238
|
+
.sh-cmt { color: #8b949e; font-style: italic; }
|
|
3239
|
+
.sh-num { color: #79c0ff; }
|
|
3019
3240
|
.footer {
|
|
3020
3241
|
padding: 10px 14px; border-top: 1px solid #21262d;
|
|
3021
3242
|
display: flex; gap: 8px; justify-content: flex-end; background: #161b22;
|
|
@@ -3031,6 +3252,12 @@ var ADVANCED_TEST_EDITOR_STYLES = `
|
|
|
3031
3252
|
.btn-save:hover { background: #1f6feb; border-color: #1f6feb; color: #fff; }
|
|
3032
3253
|
.btn-save:disabled { background: #21262d; border-color: #30363d; color: #8b949e; }
|
|
3033
3254
|
.placeholder { color: #484f58; font-size: 13px; padding: 28px; text-align: center; }
|
|
3255
|
+
.test-notes {
|
|
3256
|
+
margin: 0 0 10px; padding: 8px 12px;
|
|
3257
|
+
background: rgba(47,129,247,0.06); border-left: 3px solid rgba(47,129,247,0.4);
|
|
3258
|
+
border-radius: 0 6px 6px 0; font-size: 12px; color: #8b949e;
|
|
3259
|
+
line-height: 1.6; white-space: pre-wrap; word-break: break-word;
|
|
3260
|
+
}
|
|
3034
3261
|
.block-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
|
|
3035
3262
|
.btn-copy {
|
|
3036
3263
|
padding: 3px 10px; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;
|
|
@@ -3083,23 +3310,24 @@ function renderNoPermission(needsReauth, t) {
|
|
|
3083
3310
|
</div>`;
|
|
3084
3311
|
}
|
|
3085
3312
|
function renderAdvancedEditor(state, t) {
|
|
3086
|
-
const { e2eTree, selectedFile, selectedFileContent, testItBlock, interceptorsBlock, saveButtonEnabled, isCreatingFile, collapsedDirs, sidebarWidth } = state;
|
|
3313
|
+
const { e2eTree, selectedFile, selectedFileContent, testItBlock, interceptorsBlock, testNotes, saveButtonEnabled, isCreatingFile, collapsedDirs, sidebarWidth } = state;
|
|
3087
3314
|
const treeHtml = e2eTree.length ? renderTree(e2eTree, selectedFile, collapsedDirs) : `<div class="tree-item" style="color:#6c7a99">${t("ADVANCED_EDITOR.NO_FILES")}</div>`;
|
|
3088
3315
|
const contentHtml = selectedFileContent ? `<div class="file-name">\u{1F4C4} ${escHtml(selectedFile?.name ?? "")}</div>
|
|
3089
|
-
<pre>${
|
|
3316
|
+
<pre class="pre-file">${syntaxHighlight(selectedFileContent.slice(0, 6e3))}${selectedFileContent.length > 6e3 ? "\n..." : ""}</pre>` : `<div class="placeholder">${t("ADVANCED_EDITOR.SELECT_FILE")}</div>`;
|
|
3317
|
+
const notesHtml = testItBlock && testNotes ? `<p class="test-notes">${escHtml(testNotes)}</p>` : "";
|
|
3090
3318
|
const itHtml = testItBlock ? `<div style="margin-top:10px">
|
|
3091
3319
|
<div class="file-name block-header">
|
|
3092
3320
|
<span>${t("ADVANCED_EDITOR.IT_LABEL")}</span>
|
|
3093
3321
|
<button id="btn-copy-it" class="btn-copy">${t("ADVANCED_EDITOR.COPY_IT_BTN")}</button>
|
|
3094
3322
|
</div>
|
|
3095
|
-
<pre
|
|
3323
|
+
<pre class="pre-block">${syntaxHighlight(testItBlock.slice(0, 3e3))}</pre>
|
|
3096
3324
|
</div>` : "";
|
|
3097
3325
|
const interceptorsHtml = interceptorsBlock ? `<div style="margin-top:10px">
|
|
3098
3326
|
<div class="file-name block-header">
|
|
3099
3327
|
<span>${t("ADVANCED_EDITOR.BEFORE_EACH_LABEL")}</span>
|
|
3100
3328
|
<button id="btn-copy-interceptors" class="btn-copy">${t("ADVANCED_EDITOR.COPY_ICP_BTN")}</button>
|
|
3101
3329
|
</div>
|
|
3102
|
-
<pre
|
|
3330
|
+
<pre class="pre-block pre-icp">${syntaxHighlight(interceptorsBlock.slice(0, 3e3))}</pre>
|
|
3103
3331
|
</div>` : "";
|
|
3104
3332
|
const newFileForm = isCreatingFile ? `<div class="new-file-form">
|
|
3105
3333
|
<input id="input-new-file" type="text" placeholder="${escHtml(t("ADVANCED_EDITOR.NEW_FILE_PLACEHOLDER"))}" autocomplete="off" />
|
|
@@ -3123,7 +3351,7 @@ function renderAdvancedEditor(state, t) {
|
|
|
3123
3351
|
</div>
|
|
3124
3352
|
<div id="resize-handle" class="resize-handle"></div>
|
|
3125
3353
|
<div class="main">
|
|
3126
|
-
<div class="content-area">${contentHtml}${itHtml}${interceptorsHtml}</div>
|
|
3354
|
+
<div class="content-area">${contentHtml}${notesHtml}${itHtml}${interceptorsHtml}</div>
|
|
3127
3355
|
<div class="footer">
|
|
3128
3356
|
<button id="btn-save" class="btn-save"
|
|
3129
3357
|
${!saveButtonEnabled || !testItBlock ? "disabled" : ""}>
|
|
@@ -3184,6 +3412,7 @@ var AdvancedTestEditorElement = class extends HTMLElement {
|
|
|
3184
3412
|
selectedFileContent = null;
|
|
3185
3413
|
testItBlock = "";
|
|
3186
3414
|
interceptorsBlock = "";
|
|
3415
|
+
testNotes = "";
|
|
3187
3416
|
isPreviewMode = false;
|
|
3188
3417
|
previewFileName = null;
|
|
3189
3418
|
previewFileContent = null;
|
|
@@ -3277,7 +3506,8 @@ var AdvancedTestEditorElement = class extends HTMLElement {
|
|
|
3277
3506
|
if (this.interceptorsBlock) {
|
|
3278
3507
|
content = this.transformationService.insertBeforeEach(content, this.interceptorsBlock);
|
|
3279
3508
|
}
|
|
3280
|
-
|
|
3509
|
+
const comment = this.testNotes ? this.transformationService.buildBlockComment(this.testNotes) + "\n" : "";
|
|
3510
|
+
content = this.transformationService.insertItBlock(content, comment + this.testItBlock);
|
|
3281
3511
|
if (!content) return;
|
|
3282
3512
|
const writable = await this.selectedFileHandle.createWritable();
|
|
3283
3513
|
await writable.write(content);
|
|
@@ -3304,9 +3534,11 @@ var AdvancedTestEditorElement = class extends HTMLElement {
|
|
|
3304
3534
|
if (test) {
|
|
3305
3535
|
this.testItBlock = test.itBlock ?? "";
|
|
3306
3536
|
this.interceptorsBlock = test.interceptorsBlock ?? "";
|
|
3537
|
+
this.testNotes = test.notes ?? "";
|
|
3307
3538
|
} else {
|
|
3308
3539
|
this.testItBlock = "";
|
|
3309
3540
|
this.interceptorsBlock = "";
|
|
3541
|
+
this.testNotes = "";
|
|
3310
3542
|
}
|
|
3311
3543
|
this.render();
|
|
3312
3544
|
}
|
|
@@ -3396,6 +3628,7 @@ var AdvancedTestEditorElement = class extends HTMLElement {
|
|
|
3396
3628
|
selectedFileContent: this.selectedFileContent,
|
|
3397
3629
|
testItBlock: this.testItBlock,
|
|
3398
3630
|
interceptorsBlock: this.interceptorsBlock,
|
|
3631
|
+
testNotes: this.testNotes,
|
|
3399
3632
|
saveButtonEnabled: this.saveButtonEnabled,
|
|
3400
3633
|
isCreatingFile: this.isCreatingFile,
|
|
3401
3634
|
collapsedDirs: this.collapsedDirs,
|
|
@@ -3962,6 +4195,7 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
3962
4195
|
recording;
|
|
3963
4196
|
persistence;
|
|
3964
4197
|
translation;
|
|
4198
|
+
isVisible = false;
|
|
3965
4199
|
isRecording = false;
|
|
3966
4200
|
isPaused = false;
|
|
3967
4201
|
cypressCommands = [];
|
|
@@ -3996,6 +4230,7 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
3996
4230
|
this.initSelectorStrategy();
|
|
3997
4231
|
this.initSubscriptions();
|
|
3998
4232
|
this.render();
|
|
4233
|
+
this.initVisibility();
|
|
3999
4234
|
this.keydownHandler = (e) => this.handleKeyboardEvent(e);
|
|
4000
4235
|
window.addEventListener("keydown", this.keydownHandler);
|
|
4001
4236
|
}
|
|
@@ -4061,6 +4296,16 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
4061
4296
|
document.body.appendChild(picker);
|
|
4062
4297
|
});
|
|
4063
4298
|
}
|
|
4299
|
+
async initVisibility() {
|
|
4300
|
+
if (this.hasAttribute("start-hidden")) {
|
|
4301
|
+
this.isVisible = this.getAttribute("start-hidden") === "false";
|
|
4302
|
+
this.style.display = this.isVisible ? "" : "none";
|
|
4303
|
+
return;
|
|
4304
|
+
}
|
|
4305
|
+
const config = await this.persistence.getGeneralConfig();
|
|
4306
|
+
this.isVisible = config?.["startHidden"] !== "true";
|
|
4307
|
+
this.style.display = this.isVisible ? "" : "none";
|
|
4308
|
+
}
|
|
4064
4309
|
async initSelectorStrategy() {
|
|
4065
4310
|
const config = await this.persistence.getGeneralConfig();
|
|
4066
4311
|
const strategy = config?.["selectorStrategy"];
|
|
@@ -4080,6 +4325,12 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
4080
4325
|
handleKeyboardEvent(event) {
|
|
4081
4326
|
if (!event.ctrlKey) return;
|
|
4082
4327
|
const key = event.key.toLowerCase();
|
|
4328
|
+
if (key === "e" && event.shiftKey) {
|
|
4329
|
+
event.preventDefault();
|
|
4330
|
+
this.toggleVisibility();
|
|
4331
|
+
return;
|
|
4332
|
+
}
|
|
4333
|
+
if (!this.isVisible) return;
|
|
4083
4334
|
if (key === "r") {
|
|
4084
4335
|
event.preventDefault();
|
|
4085
4336
|
this.toggle();
|
|
@@ -4097,6 +4348,10 @@ var LibE2eRecorderElement = class extends HTMLElement {
|
|
|
4097
4348
|
this.showSettingsDialog();
|
|
4098
4349
|
}
|
|
4099
4350
|
}
|
|
4351
|
+
toggleVisibility() {
|
|
4352
|
+
this.isVisible = !this.isVisible;
|
|
4353
|
+
this.style.display = this.isVisible ? "" : "none";
|
|
4354
|
+
}
|
|
4100
4355
|
// ── recording history (task 5) ────────────────────────────────────────────
|
|
4101
4356
|
saveRecordingHistory() {
|
|
4102
4357
|
if (!this.cypressCommands.length) return;
|
|
@@ -4332,13 +4587,13 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
4332
4587
|
child.translation = this.translation;
|
|
4333
4588
|
container.appendChild(child);
|
|
4334
4589
|
child.addEventListener("savetest", (e) => {
|
|
4335
|
-
const { description, tags } = e.detail ?? {};
|
|
4336
|
-
this.onSaveTest(description ?? null, tags ?? []);
|
|
4590
|
+
const { description, notes, tags } = e.detail ?? {};
|
|
4591
|
+
this.onSaveTest(description ?? null, tags ?? [], notes ?? "");
|
|
4337
4592
|
Swal.close();
|
|
4338
4593
|
});
|
|
4339
4594
|
child.addEventListener("saveandexport", (e) => {
|
|
4340
|
-
const { description, tags } = e.detail ?? {};
|
|
4341
|
-
this.onSaveAndExportTest(description ?? null, tags ?? []);
|
|
4595
|
+
const { description, notes, tags } = e.detail ?? {};
|
|
4596
|
+
this.onSaveAndExportTest(description ?? null, tags ?? [], notes ?? "");
|
|
4342
4597
|
Swal.close();
|
|
4343
4598
|
});
|
|
4344
4599
|
},
|
|
@@ -4369,6 +4624,10 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
4369
4624
|
child.addEventListener("smartselectorchange", (e) => {
|
|
4370
4625
|
this.smartSelectorEnabled = e.detail;
|
|
4371
4626
|
});
|
|
4627
|
+
child.addEventListener("starthiddenchange", (e) => {
|
|
4628
|
+
this.isVisible = !e.detail;
|
|
4629
|
+
this.style.display = this.isVisible ? "" : "none";
|
|
4630
|
+
});
|
|
4372
4631
|
},
|
|
4373
4632
|
willClose: () => {
|
|
4374
4633
|
this.isSettingsDialogOpen = false;
|
|
@@ -4480,18 +4739,18 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
4480
4739
|
this.resizePopup();
|
|
4481
4740
|
}
|
|
4482
4741
|
// ── save handlers ─────────────────────────────────────────────────────────
|
|
4483
|
-
async onSaveTest(description, tags = []) {
|
|
4742
|
+
async onSaveTest(description, tags = [], notes = "") {
|
|
4484
4743
|
if (description) {
|
|
4485
|
-
await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags);
|
|
4744
|
+
await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags, notes);
|
|
4486
4745
|
this.recording.clearCommands();
|
|
4487
4746
|
this.clearRecordingHistory();
|
|
4488
4747
|
this.cypressCommands = [];
|
|
4489
4748
|
this.interceptors = [];
|
|
4490
4749
|
}
|
|
4491
4750
|
}
|
|
4492
|
-
async onSaveAndExportTest(description, tags = []) {
|
|
4751
|
+
async onSaveAndExportTest(description, tags = [], notes = "") {
|
|
4493
4752
|
if (description) {
|
|
4494
|
-
const id = await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags);
|
|
4753
|
+
const id = await this.persistence.insertTest(description, this.cypressCommands, this.interceptors, tags, notes);
|
|
4495
4754
|
this.recording.clearCommands();
|
|
4496
4755
|
this.clearRecordingHistory();
|
|
4497
4756
|
this.cypressCommands = [];
|
|
@@ -4518,6 +4777,7 @@ cypress/ <span style="color:#484f58">${this.translation.translate("RECOR
|
|
|
4518
4777
|
render() {
|
|
4519
4778
|
const rec = this.isRecording;
|
|
4520
4779
|
const paused = this.isPaused;
|
|
4780
|
+
this.style.display = this.isVisible ? "" : "none";
|
|
4521
4781
|
this.shadow.innerHTML = `<style>${getRecorderStyles(rec, paused)}</style>${renderRecorderWidget(rec, paused, this.translation.translate.bind(this.translation))}`;
|
|
4522
4782
|
this.shadow.querySelector('[data-action="toggle"]')?.addEventListener("click", () => this.toggle());
|
|
4523
4783
|
this.shadow.querySelector('[data-action="pause"]')?.addEventListener("click", () => this.togglePause());
|