oh gott was mach ich nur
This commit is contained in:
@@ -13,7 +13,9 @@
|
||||
setOverallStatus,
|
||||
formatBytes,
|
||||
formatMbps,
|
||||
formatDuration
|
||||
formatDuration,
|
||||
t,
|
||||
tFmt
|
||||
} = window.usbcheck;
|
||||
|
||||
const root = document.getElementById("fc-root");
|
||||
@@ -53,19 +55,19 @@
|
||||
|
||||
class UsbBrowserTester {
|
||||
constructor() {
|
||||
this.rootHandle = null;
|
||||
this.abortController = null;
|
||||
this.rootHandle = null;
|
||||
this.abortController = null;
|
||||
this.capacityBytes = null;
|
||||
this.capacityProbeFile = "usbcheck_capacity_probe.bin";
|
||||
}
|
||||
|
||||
hasFsApiSupport() {
|
||||
return "showDirectoryPicker" in window;
|
||||
}
|
||||
|
||||
// Wird aktuell nicht mehr verwendet (Picker ist direkt im Click-Handler),
|
||||
// kann aber als Fallback/Refactoring-Hook bleiben.
|
||||
async pickDirectory() {
|
||||
if (!this.hasFsApiSupport()) {
|
||||
throw new Error("File System Access API wird von diesem Browser nicht unterstützt.");
|
||||
throw new Error(t("fake_ui.error_fsapi_not_supported", "File System Access API wird von diesem Browser nicht unterstützt."));
|
||||
}
|
||||
const handle = await window.showDirectoryPicker();
|
||||
this.rootHandle = handle;
|
||||
@@ -74,21 +76,120 @@
|
||||
|
||||
async clearSelection() {
|
||||
this.rootHandle = null;
|
||||
this.capacityBytes = null;
|
||||
}
|
||||
|
||||
// Freispeicher-Ermittlung
|
||||
async ensureCapacity(abortSignal) {
|
||||
if (this.capacityBytes != null) return this.capacityBytes;
|
||||
if (!this.rootHandle) {
|
||||
throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
}
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
const PROBE_FILENAME = this.capacityProbeFile;
|
||||
const CHUNK_SIZE = 1024 * 1024; // 1 MiB
|
||||
const MAX_BYTES = 128 * 1024 * 1024; // max. 128 MiB testen
|
||||
|
||||
logLine(t("fake_ui.log_capacity_probe_start", "Ermittle verfügbaren Speicherplatz im gewählten Verzeichnis..."), "info");
|
||||
|
||||
let bytesWritten = 0;
|
||||
let writable = null;
|
||||
|
||||
try {
|
||||
const fileHandle = await dirHandle.getFileHandle(PROBE_FILENAME, { create: true });
|
||||
writable = await fileHandle.createWritable();
|
||||
|
||||
const chunk = new Uint8Array(CHUNK_SIZE);
|
||||
chunk.fill(0x5a);
|
||||
|
||||
while (bytesWritten + CHUNK_SIZE <= MAX_BYTES) {
|
||||
if (abortSignal && abortSignal.aborted) {
|
||||
await writable.abort();
|
||||
throw new DOMException("Abgebrochen", "AbortError");
|
||||
}
|
||||
|
||||
await writable.write(chunk);
|
||||
bytesWritten += CHUNK_SIZE;
|
||||
}
|
||||
|
||||
await writable.close();
|
||||
} catch (err) {
|
||||
if (writable) {
|
||||
try { await writable.close(); } catch (e) {}
|
||||
}
|
||||
if (err && err.name === "AbortError") {
|
||||
throw err;
|
||||
}
|
||||
// sonst: „Out of space“ → okay, wir nehmen bytesWritten als Limit
|
||||
} finally {
|
||||
try {
|
||||
await dirHandle.removeEntry(PROBE_FILENAME);
|
||||
} catch (e) {
|
||||
// egal
|
||||
}
|
||||
}
|
||||
|
||||
if (!bytesWritten) {
|
||||
throw new Error(t("fake_ui.error_no_space_detected", "Es konnte kein freier Speicher im gewählten Verzeichnis reserviert werden."));
|
||||
}
|
||||
|
||||
this.capacityBytes = bytesWritten;
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_capacity_probe_result",
|
||||
"Ermittelter für Tests nutzbarer Speicher: {size} (Schreibprobe).",
|
||||
{ size: formatBytes(bytesWritten) }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
return this.capacityBytes;
|
||||
}
|
||||
|
||||
planSizeBytes({ defaultMB, minMB, maxFraction }) {
|
||||
const MiB = 1024 * 1024;
|
||||
const cap = this.capacityBytes || (64 * MiB);
|
||||
|
||||
const minBytes = (minMB || 1) * MiB;
|
||||
const defaultBytes = (defaultMB || 8) * MiB;
|
||||
const maxBytesByCap = Math.max(minBytes, cap * (maxFraction || 0.25));
|
||||
|
||||
let target = Math.min(defaultBytes, maxBytesByCap);
|
||||
|
||||
const CHUNK_SIZE = MiB;
|
||||
target = Math.floor(target / CHUNK_SIZE) * CHUNK_SIZE;
|
||||
if (target < CHUNK_SIZE) target = CHUNK_SIZE;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
// Quick-Check
|
||||
async runQuickCheck(report, progressCb, abortSignal) {
|
||||
const TEST_FILENAME = "usbcheck_quick_test.bin";
|
||||
const TEST_SIZE_MB = 8;
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
if (!dirHandle) throw new Error("Kein Verzeichnis ausgewählt.");
|
||||
if (!dirHandle) throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
|
||||
const totalBytes = this.planSizeBytes({
|
||||
defaultMB: 8,
|
||||
minMB: 1,
|
||||
maxFraction: 0.25
|
||||
});
|
||||
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_quick_prepare",
|
||||
"Quick-Check: Vorbereitung... (Testgröße: {size})",
|
||||
{ size: formatBytes(totalBytes) }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
logLine("Quick-Check: Vorbereitung...", "info");
|
||||
const fileHandle = await dirHandle.getFileHandle(TEST_FILENAME, { create: true });
|
||||
const writable = await fileHandle.createWritable();
|
||||
|
||||
const totalBytes = TEST_SIZE_MB * 1024 * 1024;
|
||||
let writtenBytes = 0;
|
||||
|
||||
const writeStart = performance.now();
|
||||
@@ -110,7 +211,7 @@
|
||||
await writable.close();
|
||||
const writeEnd = performance.now();
|
||||
|
||||
logLine("Quick-Check: Schreiben abgeschlossen. Verifiziere Daten...", "info");
|
||||
logLine(t("fake_ui.log_quick_verify_start", "Quick-Check: Schreiben abgeschlossen. Verifiziere Daten..."), "info");
|
||||
|
||||
const file = await fileHandle.getFile();
|
||||
const readStart = performance.now();
|
||||
@@ -129,8 +230,21 @@
|
||||
for (let i = 0; i < chunk.length; i++) {
|
||||
const expected = (offset + i) % 251;
|
||||
if (chunk[i] !== expected) {
|
||||
logLine(`Quick-Check: Datenfehler bei Byte ${offset + i}`, "error");
|
||||
throw new Error(`Datenfehler im Quick-Check bei Byte ${offset + i}`);
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_quick_data_error",
|
||||
"Quick-Check: Datenfehler bei Byte {byte}",
|
||||
{ byte: (offset + i).toString() }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
throw new Error(
|
||||
tFmt(
|
||||
"fake_ui.error_quick_data_error",
|
||||
"Datenfehler im Quick-Check bei Byte {byte}",
|
||||
{ byte: (offset + i).toString() }
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
offset += chunk.length;
|
||||
@@ -156,22 +270,41 @@
|
||||
ok: true
|
||||
};
|
||||
|
||||
logLine("Quick-Check: Erfolgreich abgeschlossen.", "info");
|
||||
try {
|
||||
await dirHandle.removeEntry(TEST_FILENAME);
|
||||
} catch (e) {
|
||||
logLine(t("fake_ui.log_quick_delete_warn", "Quick-Check: Konnte Testdatei nicht löschen (nicht kritisch)."), "warn");
|
||||
}
|
||||
|
||||
logLine(t("fake_ui.log_quick_success", "Quick-Check: Erfolgreich abgeschlossen."), "info");
|
||||
}
|
||||
|
||||
// Benchmark
|
||||
async runBenchmark(report, progressCb, abortSignal) {
|
||||
const TEST_FILENAME = "usbcheck_benchmark.bin";
|
||||
const TEST_SIZE_MB = 32;
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
if (!dirHandle) throw new Error("Kein Verzeichnis ausgewählt.");
|
||||
if (!dirHandle) throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
|
||||
const totalBytes = this.planSizeBytes({
|
||||
defaultMB: 32,
|
||||
minMB: 4,
|
||||
maxFraction: 0.5
|
||||
});
|
||||
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_bench_start",
|
||||
"Benchmark: Start – schreibe Testdatei ({size})...",
|
||||
{ size: formatBytes(totalBytes) }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
logLine("Benchmark: Start – schreibe Testdatei...", "info");
|
||||
const fileHandle = await dirHandle.getFileHandle(TEST_FILENAME, { create: true });
|
||||
const writable = await fileHandle.createWritable();
|
||||
|
||||
const totalBytes = TEST_SIZE_MB * 1024 * 1024;
|
||||
let writtenBytes = 0;
|
||||
|
||||
const writeStart = performance.now();
|
||||
@@ -193,7 +326,7 @@
|
||||
await writable.close();
|
||||
const writeEnd = performance.now();
|
||||
|
||||
logLine("Benchmark: Lesen & Timing...", "info");
|
||||
logLine(t("fake_ui.log_bench_read_start", "Benchmark: Lesen & Timing..."), "info");
|
||||
|
||||
const file = await fileHandle.getFile();
|
||||
const readStart = performance.now();
|
||||
@@ -227,22 +360,51 @@
|
||||
ok: true
|
||||
};
|
||||
|
||||
logLine("Benchmark: Erfolgreich abgeschlossen.", "info");
|
||||
try {
|
||||
await dirHandle.removeEntry(TEST_FILENAME);
|
||||
} catch (e) {
|
||||
logLine(t("fake_ui.log_bench_delete_warn", "Benchmark: Konnte Testdatei nicht löschen (nicht kritisch)."), "warn");
|
||||
}
|
||||
|
||||
logLine(t("fake_ui.log_bench_success", "Benchmark: Erfolgreich abgeschlossen."), "info");
|
||||
}
|
||||
|
||||
// Write/Verify
|
||||
async runWriteVerify(report, progressCb, abortSignal) {
|
||||
const BASE_FILENAME = "usbcheck_block_";
|
||||
const BLOCKS = 4;
|
||||
const BLOCK_SIZE_MB = 32;
|
||||
const CHUNK_SIZE = 1024 * 1024;
|
||||
|
||||
const dirHandle = this.rootHandle;
|
||||
if (!dirHandle) throw new Error("Kein Verzeichnis ausgewählt.");
|
||||
if (!dirHandle) throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
|
||||
logLine("Write/Verify: Start – mehrere Blöcke werden getestet...", "info");
|
||||
const totalBytesPlanned = this.planSizeBytes({
|
||||
defaultMB: 128,
|
||||
minMB: 8,
|
||||
maxFraction: 0.75
|
||||
});
|
||||
|
||||
const totalBytes = BLOCKS * BLOCK_SIZE_MB * 1024 * 1024;
|
||||
let writtenBytes = 0;
|
||||
const blockBytes = Math.max(
|
||||
CHUNK_SIZE,
|
||||
Math.floor(totalBytesPlanned / BLOCKS / CHUNK_SIZE) * CHUNK_SIZE
|
||||
);
|
||||
|
||||
const totalBytes = blockBytes * BLOCKS;
|
||||
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_start",
|
||||
"Write/Verify: Start – {blocks} Blöcke à {size} (gesamt {total})...",
|
||||
{
|
||||
blocks: BLOCKS.toString(),
|
||||
size: formatBytes(blockBytes),
|
||||
total: formatBytes(totalBytes)
|
||||
}
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
let writtenBytes = 0;
|
||||
let verifiedBytes = 0;
|
||||
|
||||
const globalStart = performance.now();
|
||||
@@ -251,21 +413,32 @@
|
||||
|
||||
for (let b = 0; b < BLOCKS; b++) {
|
||||
const filename = `${BASE_FILENAME}${String(b + 1).padStart(2, "0")}.bin`;
|
||||
logLine(`Write/Verify: Block ${b + 1}/${BLOCKS} – ${filename}`, "info");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_block_start",
|
||||
"Write/Verify: Block {num}/{blocks} – {file}",
|
||||
{
|
||||
num: (b + 1).toString(),
|
||||
blocks: BLOCKS.toString(),
|
||||
file: filename
|
||||
}
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
const fileHandle = await dirHandle.getFileHandle(filename, { create: true });
|
||||
const writable = await fileHandle.createWritable();
|
||||
|
||||
const blockBytes = BLOCK_SIZE_MB * 1024 * 1024;
|
||||
const blockBytesTotal = blockBytes;
|
||||
let blockWritten = 0;
|
||||
const blockWriteStart = performance.now();
|
||||
|
||||
while (blockWritten < blockBytes) {
|
||||
while (blockWritten < blockBytesTotal) {
|
||||
if (abortSignal.aborted) {
|
||||
await writable.abort();
|
||||
throw new DOMException("Abgebrochen", "AbortError");
|
||||
}
|
||||
const remaining = blockBytes - blockWritten;
|
||||
const remaining = blockBytesTotal - blockWritten;
|
||||
const chunkLen = Math.min(CHUNK_SIZE, remaining);
|
||||
const chunk = new Uint8Array(chunkLen);
|
||||
for (let i = 0; i < chunkLen; i++) {
|
||||
@@ -281,7 +454,7 @@
|
||||
const blockWriteEnd = performance.now();
|
||||
writeDetails.push({
|
||||
block: b + 1,
|
||||
bytes: blockBytes,
|
||||
bytes: blockBytesTotal,
|
||||
duration_s: (blockWriteEnd - blockWriteStart) / 1000
|
||||
});
|
||||
|
||||
@@ -301,8 +474,27 @@
|
||||
for (let i = 0; i < chunk.length; i++) {
|
||||
const expected = (i + blockOffset + b * 13) % 251;
|
||||
if (chunk[i] !== expected) {
|
||||
logLine(`Write/Verify: Datenfehler in Block ${b + 1} bei Byte ${blockOffset + i}`, "error");
|
||||
throw new Error(`Datenfehler in Block ${b + 1} bei Byte ${blockOffset + i}`);
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_data_error",
|
||||
"Write/Verify: Datenfehler in Block {num} bei Byte {byte}",
|
||||
{
|
||||
num: (b + 1).toString(),
|
||||
byte: (blockOffset + i).toString()
|
||||
}
|
||||
),
|
||||
"error"
|
||||
);
|
||||
throw new Error(
|
||||
tFmt(
|
||||
"fake_ui.error_wv_data_error",
|
||||
"Datenfehler in Block {num} bei Byte {byte}",
|
||||
{
|
||||
num: (b + 1).toString(),
|
||||
byte: (blockOffset + i).toString()
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
blockOffset += chunk.length;
|
||||
@@ -313,9 +505,22 @@
|
||||
const blockReadEnd = performance.now();
|
||||
readDetails.push({
|
||||
block: b + 1,
|
||||
bytes: blockBytes,
|
||||
bytes: blockBytesTotal,
|
||||
duration_s: (blockReadEnd - blockReadStart) / 1000
|
||||
});
|
||||
|
||||
try {
|
||||
await dirHandle.removeEntry(filename);
|
||||
} catch (e) {
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_wv_delete_warn",
|
||||
"Write/Verify: Konnte Blockdatei {file} nicht löschen (nicht kritisch).",
|
||||
{ file: filename }
|
||||
),
|
||||
"warn"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const globalEnd = performance.now();
|
||||
@@ -329,7 +534,7 @@
|
||||
report.writeverify = {
|
||||
mode: "writeverify",
|
||||
blocks: BLOCKS,
|
||||
block_size_mb: BLOCK_SIZE_MB,
|
||||
block_size_bytes: blockBytes,
|
||||
total_bytes: totalBytes,
|
||||
written_bytes: writtenBytes,
|
||||
verified_bytes: verifiedBytes,
|
||||
@@ -342,18 +547,20 @@
|
||||
|
||||
report.writeverify_total_duration_s = totalDuration;
|
||||
|
||||
logLine("Write/Verify: Alle Blöcke erfolgreich verifiziert.", "info");
|
||||
logLine(t("fake_ui.log_wv_success", "Write/Verify: Alle Blöcke erfolgreich verifiziert."), "info");
|
||||
}
|
||||
|
||||
async run(mode, updateProgressCb, abortSignal) {
|
||||
if (!this.rootHandle) {
|
||||
throw new Error("Kein USB-Verzeichnis ausgewählt.");
|
||||
throw new Error(t("fake_ui.error_no_directory_selected", "Kein Verzeichnis ausgewählt."));
|
||||
}
|
||||
|
||||
await this.ensureCapacity(abortSignal);
|
||||
|
||||
const report = {
|
||||
meta: {
|
||||
base_url: cfg.baseUrl || "",
|
||||
locale: cfg.locale || "en",
|
||||
locale: cfg.locale || "en",
|
||||
user_agent: navigator.userAgent,
|
||||
started_at: new Date().toISOString()
|
||||
},
|
||||
@@ -375,11 +582,21 @@
|
||||
} else if (mode === "writeverify") {
|
||||
await this.runWriteVerify(report, updateProgressCb, abortSignal);
|
||||
} else if (mode === "all") {
|
||||
// Alle drei Tests nacheinander im selben Report
|
||||
const modes = ["quick", "benchmark", "writeverify"];
|
||||
for (let i = 0; i < modes.length; i++) {
|
||||
const subMode = modes[i];
|
||||
logLine(`All-Inclusive: Starte Teiltest "${subMode}" (${i + 1}/${modes.length})...`, "info");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_all_subtest_start",
|
||||
"All-Inclusive: Starte Teiltest \"{mode}\" ({num}/{total})...",
|
||||
{
|
||||
mode: subMode,
|
||||
num: (i + 1).toString(),
|
||||
total: modes.length.toString()
|
||||
}
|
||||
),
|
||||
"info"
|
||||
);
|
||||
|
||||
const base = (i / modes.length) * 100;
|
||||
const span = (1 / modes.length) * 100;
|
||||
@@ -397,7 +614,7 @@
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error("Unbekannter Modus: " + mode);
|
||||
throw new Error(tFmt("fake_ui.error_unknown_mode", "Unbekannter Modus: {mode}", { mode }));
|
||||
}
|
||||
|
||||
const t1 = performance.now();
|
||||
@@ -415,7 +632,7 @@
|
||||
if (!tester.hasFsApiSupport()) {
|
||||
if (fsapiWarning) fsapiWarning.style.display = "block";
|
||||
logLine(
|
||||
"Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert.",
|
||||
t("fake_ui.log_fsapi_partial", "Dein Browser unterstützt die File System Access API nicht voll. Einige Funktionen sind deaktiviert."),
|
||||
"warn"
|
||||
);
|
||||
}
|
||||
@@ -429,8 +646,6 @@
|
||||
|
||||
// --- Event-Handler ------------------------------------------------------
|
||||
|
||||
// Wichtig: showDirectoryPicker direkt im Click-Handler per Promise,
|
||||
// kein async/await direkt im Listener → vermeidet "User activation is required".
|
||||
let isPickingDir = false;
|
||||
|
||||
if (btnPickDir) {
|
||||
@@ -439,7 +654,7 @@
|
||||
isPickingDir = true;
|
||||
|
||||
if (!("showDirectoryPicker" in window)) {
|
||||
logLine("File System Access API wird von diesem Browser nicht unterstützt.", "error");
|
||||
logLine(t("fake_ui.error_fsapi_not_supported", "File System Access API wird von diesem Browser nicht unterstützt."), "error");
|
||||
if (fsapiWarning) fsapiWarning.style.display = "block";
|
||||
isPickingDir = false;
|
||||
return;
|
||||
@@ -447,23 +662,42 @@
|
||||
|
||||
window.showDirectoryPicker()
|
||||
.then((handle) => {
|
||||
tester.rootHandle = handle;
|
||||
tester.rootHandle = handle;
|
||||
tester.capacityBytes = null;
|
||||
|
||||
if (selectedPathText) {
|
||||
selectedPathText.textContent =
|
||||
'USB-Ordner ausgewählt (Name: "' + (handle.name || "Unbekannt") + '").';
|
||||
selectedPathText.textContent = tFmt(
|
||||
"fake_ui.selected_path_label",
|
||||
'USB-Ordner ausgewählt (Name: "{name}").',
|
||||
{ name: (handle.name || "Unbekannt") }
|
||||
);
|
||||
}
|
||||
if (btnClearSel) btnClearSel.disabled = false;
|
||||
setStatus("USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus.");
|
||||
logLine("Verzeichnis ausgewählt: " + (handle.name || "[ohne Namen]"));
|
||||
setStatus(t("fake_ui.status_dir_selected", "USB-Verzeichnis ausgewählt. Wähle jetzt einen Testmodus."));
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_dir_selected",
|
||||
"Verzeichnis ausgewählt: {name}",
|
||||
{ name: (handle.name || "[ohne Namen]") }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
updateStartButtonState();
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err && err.name === "AbortError") {
|
||||
logLine("Verzeichnisauswahl abgebrochen.", "warn");
|
||||
logLine(t("fake_ui.log_pick_abort", "Verzeichnisauswahl abgebrochen."), "warn");
|
||||
} else if (err) {
|
||||
logLine("Fehler bei Verzeichnisauswahl: " + err.message, "error");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_pick_error",
|
||||
"Fehler bei Verzeichnisauswahl: {msg}",
|
||||
{ msg: err.message || "unbekannt" }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
} else {
|
||||
logLine("Unbekannter Fehler bei Verzeichnisauswahl.", "error");
|
||||
logLine(t("fake_ui.log_pick_error_unknown", "Unbekannter Fehler bei Verzeichnisauswahl."), "error");
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -476,11 +710,11 @@
|
||||
btnClearSel.addEventListener("click", async () => {
|
||||
await tester.clearSelection();
|
||||
if (selectedPathText) {
|
||||
selectedPathText.textContent = "Noch kein Verzeichnis gewählt.";
|
||||
selectedPathText.textContent = t("fake_ui.selected_path_none", "Noch kein Verzeichnis gewählt.");
|
||||
}
|
||||
btnClearSel.disabled = true;
|
||||
setStatus("Bereit. Wähle zuerst deinen USB-Stick aus.");
|
||||
logLine("Verzeichnisauswahl zurückgesetzt.", "info");
|
||||
setStatus(t("fake_ui.status_ready", "Bereit. Wähle zuerst deinen USB-Stick aus."));
|
||||
logLine(t("fake_ui.log_dir_reset", "Verzeichnisauswahl zurückgesetzt."), "info");
|
||||
updateStartButtonState();
|
||||
});
|
||||
}
|
||||
@@ -489,14 +723,27 @@
|
||||
tile.addEventListener("click", () => {
|
||||
if (tile.classList.contains("disabled")) return;
|
||||
if (isRunning) return;
|
||||
modeTiles.forEach((t) => t.classList.remove("selected"));
|
||||
modeTiles.forEach((tEl) => tEl.classList.remove("selected"));
|
||||
tile.classList.add("selected");
|
||||
currentMode = tile.getAttribute("data-mode");
|
||||
const titleEl = tile.querySelector("h4");
|
||||
const label = titleEl ? titleEl.textContent : currentMode;
|
||||
setModeLabel(label || "");
|
||||
setStatus(`Modus "${label}" ausgewählt. Du kannst den Test jetzt starten.`);
|
||||
logLine("Modus gewählt: " + currentMode, "info");
|
||||
setStatus(
|
||||
tFmt(
|
||||
"fake_ui.status_mode_selected",
|
||||
'Modus "{mode}" ausgewählt. Du kannst den Test jetzt starten.',
|
||||
{ mode: label || currentMode || "" }
|
||||
)
|
||||
);
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_mode_selected",
|
||||
"Modus gewählt: {mode}",
|
||||
{ mode: currentMode || "" }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
updateStartButtonState();
|
||||
});
|
||||
});
|
||||
@@ -509,9 +756,16 @@
|
||||
if (btnCancel) btnCancel.disabled = false;
|
||||
if (saveError) saveError.style.display = "none";
|
||||
setProgress(0);
|
||||
logLine("Starte Tests im Modus: " + currentMode.toUpperCase(), "info");
|
||||
setStatus("Test läuft... bitte USB-Stick nicht entfernen.");
|
||||
setOverallStatus("warn", "Test läuft...");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_test_start",
|
||||
"Starte Tests im Modus: {mode}",
|
||||
{ mode: (currentMode || "").toUpperCase() }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
setStatus(t("fake_ui.status_running", "Test läuft... bitte USB-Stick nicht entfernen."));
|
||||
setOverallStatus("warn", t("fake_ui.overall_running", "Test läuft..."));
|
||||
|
||||
const abortController = new AbortController();
|
||||
tester.abortController = abortController;
|
||||
@@ -523,8 +777,8 @@
|
||||
report = await tester.run(currentMode, updateProgressCb, abortController.signal);
|
||||
|
||||
setProgress(100);
|
||||
setStatus("Test abgeschlossen.");
|
||||
setOverallStatus("ok", "Browser-Test erfolgreich abgeschlossen.");
|
||||
setStatus(t("fake_ui.status_done", "Test abgeschlossen."));
|
||||
setOverallStatus("ok", t("fake_ui.overall_done", "Browser-Test erfolgreich abgeschlossen."));
|
||||
applyReportToDashboard(report);
|
||||
|
||||
console.log("USB Browser Test Report (fakecheck):", report);
|
||||
@@ -532,17 +786,30 @@
|
||||
await saveReportToBackend(report);
|
||||
} catch (err) {
|
||||
if (err && err.name === "AbortError") {
|
||||
setStatus("Test wurde abgebrochen.");
|
||||
setOverallStatus("warn", "Test abgebrochen.");
|
||||
logLine("Test wurde vom Benutzer abgebrochen.", "warn");
|
||||
setStatus(t("fake_ui.status_aborted", "Test wurde abgebrochen."));
|
||||
setOverallStatus("warn", t("fake_ui.overall_aborted", "Test abgebrochen."));
|
||||
logLine(t("fake_ui.log_test_aborted", "Test wurde vom Benutzer abgebrochen."), "warn");
|
||||
} else if (err) {
|
||||
setStatus("Fehler: " + err.message);
|
||||
setOverallStatus("bad", "Fehler im Browser-Test.");
|
||||
logLine("Fehler im Test: " + err.message, "error");
|
||||
setStatus(
|
||||
tFmt(
|
||||
"fake_ui.status_error",
|
||||
"Fehler: {msg}",
|
||||
{ msg: err.message || "unbekannt" }
|
||||
)
|
||||
);
|
||||
setOverallStatus("bad", t("fake_ui.overall_error", "Fehler im Browser-Test."));
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_test_error",
|
||||
"Fehler im Test: {msg}",
|
||||
{ msg: err.message || "unbekannt" }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
} else {
|
||||
setStatus("Unbekannter Fehler im Test.");
|
||||
setOverallStatus("bad", "Fehler im Browser-Test.");
|
||||
logLine("Unbekannter Fehler im Test.", "error");
|
||||
setStatus(t("fake_ui.status_error_unknown", "Unbekannter Fehler im Test."));
|
||||
setOverallStatus("bad", t("fake_ui.overall_error", "Fehler im Browser-Test."));
|
||||
logLine(t("fake_ui.log_test_error_unknown", "Unbekannter Fehler im Test."), "error");
|
||||
}
|
||||
} finally {
|
||||
isRunning = false;
|
||||
@@ -564,10 +831,10 @@
|
||||
|
||||
function applyReportToDashboard(report) {
|
||||
const modeLabelMap = {
|
||||
quick: "Quick-Check",
|
||||
benchmark: "Benchmark",
|
||||
writeverify: "Write & Verify",
|
||||
all: "All-Inclusive (alle Browser-Tests)"
|
||||
quick: t("fake_ui.mode_quick", "Quick-Check"),
|
||||
benchmark: t("fake_ui.mode_benchmark", "Benchmark"),
|
||||
writeverify: t("fake_ui.mode_writeverify", "Write & Verify"),
|
||||
all: t("fake_ui.mode_all", "All-Inclusive (alle Browser-Tests)")
|
||||
};
|
||||
|
||||
if (resMode) {
|
||||
@@ -631,7 +898,14 @@
|
||||
|
||||
if (!response.ok) {
|
||||
const msg = "HTTP " + response.status;
|
||||
logLine("Backend: Konnte Ergebnis nicht speichern (" + msg + ").", "warn");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_backend_save_error_status",
|
||||
"Backend: Konnte Ergebnis nicht speichern ({status}).",
|
||||
{ status: msg }
|
||||
),
|
||||
"warn"
|
||||
);
|
||||
if (response.status >= 500 && saveError) {
|
||||
saveError.style.display = "block";
|
||||
}
|
||||
@@ -640,21 +914,34 @@
|
||||
|
||||
const data = await response.json().catch(() => null);
|
||||
logLine(
|
||||
"Backend: Testergebnis gespeichert" +
|
||||
(data && data.id ? ` (ID: ${data.id})` : ""),
|
||||
tFmt(
|
||||
"fake_ui.log_backend_save_ok",
|
||||
"Backend: Testergebnis gespeichert{suffix}",
|
||||
{ suffix: (data && data.id ? ` (ID: ${data.id})` : "") }
|
||||
),
|
||||
"info"
|
||||
);
|
||||
} catch (err) {
|
||||
if (saveError) saveError.style.display = "block";
|
||||
logLine("Fehler beim Speichern im Backend: " + (err ? err.message : "unbekannt"), "error");
|
||||
logLine(
|
||||
tFmt(
|
||||
"fake_ui.log_backend_save_error",
|
||||
"Fehler beim Speichern im Backend: {msg}",
|
||||
{ msg: err ? err.message || "unbekannt" : "unbekannt" }
|
||||
),
|
||||
"error"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Initialzustand -----------------------------------------------------
|
||||
|
||||
setStatus("Bereit. Wähle zuerst deinen USB-Stick aus.");
|
||||
setModeLabel("Kein Modus selektiert");
|
||||
setOverallStatus("ok", "Noch kein Test durchgeführt.");
|
||||
logLine("USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus.");
|
||||
setStatus(t("fake_ui.status_ready", "Bereit. Wähle zuerst deinen USB-Stick aus."));
|
||||
setModeLabel(t("fake_ui.status_mode_none", "Kein Modus selektiert"));
|
||||
setOverallStatus("ok", t("fake_ui.overall_initial", "Noch kein Test durchgeführt."));
|
||||
logLine(
|
||||
t("fake_ui.log_loaded", "USB-Browser-Test (fakecheck) geladen. Warte auf Verzeichnisauswahl und Modus."),
|
||||
"info"
|
||||
);
|
||||
updateStartButtonState();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user