Wizard: User erst beim Abschliessen, Reihenfolge Sprache/Design/Modus, Reset im Einzelmodus
Image bauen und in die Registry schieben / build (push) Successful in 6s
Image bauen und in die Registry schieben / build (push) Successful in 6s
- Benutzer wird erst beim 'Einrichtung abschliessen' angelegt (POST /api/register im wizardFinish); bis dahin frei umentscheidbar, im Modus- Schritt Hinweis + Live-Validierung (Finish deaktiviert bis ausgefuellt) - Reihenfolge: Sprache -> Darstellung (Theme/OLED/Akzent) -> Modus (Einzel/Mehrbenutzer); Onboarding bleibt Sprache -> Darstellung - Sprach-Schritt: Repo-Link + Kurztext zum Starten (nutzt den Raum) - Wizard-Modal: min-height statt fixer Hoehe -> Modus-Schritt mit Formular wird nicht mehr abgeschnitten - Server-Reset auch im Einzelmodus moeglich (nur Bestaetigungstext, kein Passwort noetig); Reset-Sektion erscheint dann entsprechend - Tests: 167 Checks gruen (39+18+52+32+26)
This commit is contained in:
1 parent
655316278a
commit
135425c781
6 files changed
+141
-108
No files matched your search
@@ -81,6 +81,8 @@ def main():
|
||||
req("PATCH", f"/api/sessions/{sess['id']}",
|
||||
{"meta": {"status": "done"}})
|
||||
|
||||
|
||||
|
||||
# --- Registrierung (erster Benutzer) --------------------------------
|
||||
st, reg = req("POST", "/api/register",
|
||||
{"username": "alex", "password": "geheim"})
|
||||
@@ -289,6 +291,14 @@ def main():
|
||||
st, _ = req("GET", "/api/sessions")
|
||||
check("Reset: Sessions ohne Anmeldung wieder sichtbar (offen)", st == 200, st)
|
||||
|
||||
# Reset im Einzelmodus (nach Owner-Reset ist der Server offen)
|
||||
st, _ = req("POST", "/api/reset", {"confirm": "RESET"})
|
||||
check("Reset im Einzelmodus: ohne Passwort -> 200", st == 200, st)
|
||||
st, _ = req("POST", "/api/reset", {"confirm": "NEIN"})
|
||||
check("Reset im Einzelmodus: falscher Text -> 400", st == 400, st)
|
||||
st, meta = req("GET", "/api/meta")
|
||||
check("nach Einzelmodus-Reset: weiterhin offen", meta["users"] == 0, meta)
|
||||
|
||||
finally:
|
||||
proc.terminate()
|
||||
proc.wait(timeout=5)
|
||||
|
||||
+4
-4
@@ -97,18 +97,18 @@ async function main() {
|
||||
&& gate().querySelectorAll(".wp-step.is-done").length === 0);
|
||||
Array.from(gate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Weiter").click();
|
||||
await waitFor(dom, d => gate().querySelectorAll(".setup-option").length === 2);
|
||||
await waitFor(dom, d => gate().querySelector(".accent-row"));
|
||||
check("Setup: Fortschritt aktualisiert",
|
||||
gate().querySelectorAll(".wp-step.is-done").length === 1
|
||||
&& gate().querySelectorAll(".wp-step.is-current").length === 1);
|
||||
Array.from(gate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Weiter").click();
|
||||
await waitFor(dom, d => gate().querySelectorAll(".setup-option").length === 2);
|
||||
const setupOptions = () => Array.from(gate().querySelectorAll(".setup-option"));
|
||||
check("Setup: zwei gleichwertige Optionen",
|
||||
setupOptions().some(b => b.textContent.includes("Mehrbenutzermodus"))
|
||||
&& setupOptions().some(b => b.textContent.includes("Einzelmodus")));
|
||||
setupOptions().find(b => b.textContent.includes("Einzelmodus")).click();
|
||||
Array.from(gate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Weiter").click();
|
||||
await waitFor(dom, d => gate().querySelector(".accent-row"));
|
||||
Array.from(gate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Einrichtung abschließen").click();
|
||||
check("Setup: Gate geschlossen nach Wizard", await waitFor(dom, d =>
|
||||
|
||||
+18
-8
@@ -85,6 +85,13 @@ check("Setup: Sprache kommt zuerst",
|
||||
Array.from(sgate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Next").click();
|
||||
await sleep(200);
|
||||
check("Setup: Darstellung kommt als zweites",
|
||||
sgate().querySelector(".wizard-title").textContent === "Appearance"
|
||||
&& !!sgate().querySelector(".accent-row")
|
||||
&& !!sgate().querySelector(".toggle-row"));
|
||||
Array.from(sgate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Next").click();
|
||||
await sleep(200);
|
||||
const setupOptions = () => Array.from(sgate().querySelectorAll(".setup-option"));
|
||||
check("Setup: zwei gleichwertige Optionen",
|
||||
setupOptions().some(b => b.textContent.includes("Multi-user mode"))
|
||||
@@ -97,15 +104,18 @@ check("Setup: Sprache kommt zuerst",
|
||||
check("Setup: Formular nach Mehrbenutzermodus-Klick",
|
||||
!!sgate().querySelector("input#setup-user")
|
||||
&& !!sgate().querySelector("input#setup-pass"));
|
||||
// Einzelmodus waehlen -> Weiter -> Darstellung -> abschliessen
|
||||
// User wird erst beim Abschliessen erstellt (nicht beim Tippen)
|
||||
sgate().querySelector("#setup-user").value = "alex";
|
||||
sgate().querySelector("#setup-pass").value = "geheim";
|
||||
sgate().querySelector("#setup-user")
|
||||
.dispatchEvent(new winSetup.window.Event("input", { bubbles: true }));
|
||||
sgate().querySelector("#setup-pass")
|
||||
.dispatchEvent(new winSetup.window.Event("input", { bubbles: true }));
|
||||
await sleep(150);
|
||||
check("Setup: User wird erst beim Abschliessen erstellt",
|
||||
(await api("GET", "/api/meta")).body.users === 0);
|
||||
// Einzelmodus waehlen -> abschliessen (User wird NICHT erstellt)
|
||||
setupOptions().find(b => b.textContent.includes("Single-user mode")).click();
|
||||
Array.from(sgate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Next").click();
|
||||
await sleep(200);
|
||||
check("Setup: Darstellung-Schritt (Theme + Akzent)",
|
||||
sgate().querySelector(".wizard-title").textContent === "Appearance"
|
||||
&& !!sgate().querySelector(".accent-row")
|
||||
&& !!sgate().querySelector(".toggle-row"));
|
||||
Array.from(sgate().querySelectorAll(".wizard-nav .btn"))
|
||||
.find(b => b.textContent === "Finish setup").click();
|
||||
await sleep(400);
|
||||
|
||||
Reference in new issue
Block a user