Hustler-Pixelwelt T13: Korrekturen Pult und Keller (Sperre laufender Aktionen, Fokus, Kontrast, Handy-Tippflächen, Pause)
Pult: laufende Anfragen je Eintrags-Id in PultList (laufRef, Brief meldet Beginn/Ende): Brief schließen und denselben Eintrag wieder öffnen sperrt alle Aktionsknöpfe, kein zweites reply/paste/start-build (P1); spätes Ergebnis nennt den Titel (P1b); Original und Entwurf pre-wrap (P3); Überschrift nimmt beim Einhängen den Fokus (M2); „Pult zuklappen“ mit aria-expanded (K4); paused -> hk-steht an der Szene (R3); Brief z-index 9 (R4); Textlinks am Handy 40 px (K7). Keller: Überschrift-Fokus (M2), Reiter-Fokusring innen (M3), Seitenzeile/Punkte/Reiterzahl in Pixelify Sans 13 px (K5), Suchfeld und Akte-Link 40 px am Handy (K7), Ortszeile mit title (W2), paused -> hk-steht (R3), Akte z-index 9 (R4); Arne ohne Eintrag neutral (R5). Tests: Sperre laufender Aktionen, Titel im späten Ergebnis, Fokus, aria-expanded, paused, pre-wrap, z-index, Tippflächen, Reiter-Fokus, Schrift, Kontrast (WCAG) von .hk-zeile-alt/.hk-kl-tag auf Papier und Hover, Arne neutral (alte „Arne schläft ohne Eintrag“-Prüfung ersetzt). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ea1485c27c
commit
0924a8d2ae
13 files changed
+597
-70
No files matched your search
@@ -758,6 +758,108 @@ test('Pult (bedient, P4-T32): während einer Anfrage sind alle Knöpfe des Brief
|
||||
} finally { ui.end() }
|
||||
})
|
||||
|
||||
// T13 P1: die Sperre gehört dem Eintrag, nicht dem Brief. Wer den Brief während einer Anfrage schließt und denselben Eintrag wieder öffnet, darf nichts zweimal auslösen
|
||||
// (sonst fügte „Antwort einfügen“ den Text doppelt ein). Aufruf der Knopf-Funktionen von Hand: ein gesperrter Knopf löst im Browser nichts aus, aber die Funktion dahinter
|
||||
// darf auch auf anderem Weg (alter Stand, Hilfstechnik) nichts senden.
|
||||
test('Pult (bedient, T13 P1): Brief schließen, während eine Anfrage läuft → denselben Eintrag öffnen → Knöpfe gesperrt, kein zweiter Aufruf → Anfrage endet → frei bzw. Brief/Meldung wie vorgesehen', async () => {
|
||||
const plattform = { ...unsicher, $id: 'k1', kind: 'plattform_antwort', title: 'Suche Webdesigner', draft: 'Claras Entwurf', sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospect: { $id: 'p1', name: 'Verein' } }
|
||||
const zweite = { ...unsicher, $id: 'e2', title: 'Zweite Rückfrage' }
|
||||
const faelle = [
|
||||
{ name: 'start-build', item: unsicher, aktion: 'start-build', schliesst: true, ok: 'wird gebaut.',
|
||||
start: async (ui) => { await ui.click('Vorschau bauen'); await ui.click('Wirklich bauen?') },
|
||||
gesperrt: ['Als Mensch antworten', 'Vorschau bauen', 'Erledigt', 'Verwerfen', 'Ich kümmere mich'] },
|
||||
{ name: 'reply', item: unsicher, aktion: 'reply', schliesst: true, ok: 'gesendet.',
|
||||
start: async (ui) => { await ui.click('Als Mensch antworten'); await ui.click('Jetzt senden') },
|
||||
gesperrt: ['Als Mensch antworten', 'Vorschau bauen', 'Erledigt', 'Verwerfen', 'Ich kümmere mich'] },
|
||||
{ name: 'paste', item: plattform, aktion: 'paste', schliesst: false, ok: 'Eingefügt. Nora sortiert die Antwort ein.',
|
||||
start: async (ui) => { await ui.click('Antwort des Kunden einfügen'); await ui.type('Antwort des Kunden', 'Ja, gern'); await ui.click('Einfügen') },
|
||||
gesperrt: ['Antwort des Kunden einfügen', 'Kopieren & öffnen', 'Als gesendet markieren', 'Verwerfen', 'Ich kümmere mich'] },
|
||||
]
|
||||
for (const fall of faelle) {
|
||||
for (const ende of ['fehler', 'erfolg']) {
|
||||
const wo = `${fall.name} / ${ende}`
|
||||
let finish
|
||||
let reject
|
||||
const api = scriptedApi(new Promise((resolve, no) => { finish = resolve; reject = no }))
|
||||
const ui = await startList([fall.item, zweite], api)
|
||||
const stale = (label) => clickable(ui.brief(), label)[0].props.onClick?.({ preventDefault() {} }) // wie ein Klick auf einen Knopf, den der Browser nicht auslöst
|
||||
try {
|
||||
// 1. die Anfrage läuft, der Brief wird geschlossen
|
||||
await ui.open(0)
|
||||
await fall.start(ui)
|
||||
assert.equal(api.calls.length, 1, wo); assert.equal(api.calls[0][1], fall.aktion, wo)
|
||||
await ui.close()
|
||||
assert.equal(ui.brief(), null, wo)
|
||||
// 2. derselbe Eintrag, neuer Brief: alles gesperrt, ein Hinweis nennt den Grund
|
||||
await ui.open(0)
|
||||
for (const label of fall.gesperrt) assert.deepEqual(ui.disabled(label), [true], `${wo}: ${label}`)
|
||||
assert.ok(ui.text().includes('Für diesen Eintrag läuft noch eine Anfrage.'), wo)
|
||||
// 3. auch die Funktionen hinter den Knöpfen senden nichts (kein zweites reply, paste oder start-build, keine Rückfrage, kein Feld, kein Öffnen der Anzeige)
|
||||
for (const label of fall.gesperrt) { stale(label); stale(label); await settle() }
|
||||
assert.equal(api.calls.length, 1, `${wo}: zweiter Aufruf`)
|
||||
assert.ok(!ui.has('Wirklich bauen?') && !ui.has('Wirklich verwerfen?') && !ui.has('Wirklich freigeben?'), `${wo}: Rückfrage`)
|
||||
assert.deepEqual([ui.value('Text der Antwort'), ui.value('Antwort des Kunden')], [[], []], `${wo}: Feld`)
|
||||
assert.equal(ui.opened.length, 0, `${wo}: Anzeige geöffnet`)
|
||||
// 4. andere Einträge sind nicht betroffen
|
||||
await ui.close(); await ui.open(1)
|
||||
assert.deepEqual(ui.disabled('Erledigt'), [false], wo); assert.ok(!ui.text().includes('Für diesen Eintrag läuft noch eine Anfrage.'), wo)
|
||||
await ui.close(); await ui.open(0)
|
||||
assert.deepEqual(ui.disabled(fall.gesperrt[0]), [true], wo)
|
||||
|
||||
// 5. die Anfrage endet
|
||||
if (ende === 'fehler') {
|
||||
reject(failure('Wird schon von einem Kollegen bearbeitet.', 409)); await settle()
|
||||
// der Brief bleibt offen, alles ist frei, der Hinweis ist weg; der späte Fehler steht bei der Liste und nennt den Eintrag
|
||||
assert.ok(ui.brief(), wo)
|
||||
for (const label of fall.gesperrt) assert.deepEqual(ui.disabled(label), [false], `${wo}: ${label}`)
|
||||
assert.ok(!ui.text().includes('Für diesen Eintrag läuft noch eine Anfrage.'), wo)
|
||||
assert.deepEqual(ui.messages(), [{ kind: 'err', text: `„${fall.item.title}“: Wird schon von einem Kollegen bearbeitet.`, role: 'alert' }], wo)
|
||||
assert.equal(api.calls.length, 1, wo)
|
||||
// wieder frei: die nächste Aktion geht hinaus
|
||||
await ui.click('Ich kümmere mich')
|
||||
assert.deepEqual(api.calls[1], [fall.item.$id, 'claim'], wo)
|
||||
} else {
|
||||
finish({ status: 'neu', item: { $id: fall.item.$id } }); await settle()
|
||||
assert.equal(api.calls.length, 1, wo)
|
||||
if (fall.schliesst) {
|
||||
// der Eintrag hat die Liste verlassen: der wieder geöffnete Brief schließt, die Meldung nennt den Titel
|
||||
assert.equal(ui.brief(), null, wo)
|
||||
assert.deepEqual(ui.messages(), [{ kind: 'ok', text: `„${fall.item.title}“ ${fall.ok}`, role: 'status' }], wo)
|
||||
} else {
|
||||
// der Eintrag bleibt: der Brief ist offen und frei, das späte Ergebnis steht mit dem Titel in der Liste
|
||||
assert.ok(ui.brief(), wo)
|
||||
for (const label of fall.gesperrt) assert.deepEqual(ui.disabled(label), [false], `${wo}: ${label}`)
|
||||
assert.deepEqual(ui.messages(), [{ kind: 'ok', text: `„${fall.item.title}“: ${fall.ok}`, role: 'status' }], wo)
|
||||
}
|
||||
}
|
||||
} finally { ui.end() }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('Pult (bedient, T13 P1): ohne Anfrage ist nichts gesperrt; die Sperre hält nur während der Anfrage und gilt je Eintrag (Brief zu, Brief auf, andere Einträge frei)', async () => {
|
||||
const zweite = { ...unsicher, $id: 'e2', title: 'Zweite Rückfrage' }
|
||||
let finish
|
||||
const api = scriptedApi(new Promise((resolve) => { finish = resolve }))
|
||||
const ui = await startList([unsicher, zweite], api)
|
||||
try {
|
||||
await ui.open(0)
|
||||
for (const label of ['Als Mensch antworten', 'Vorschau bauen', 'Erledigt', 'Verwerfen', 'Ich kümmere mich']) assert.deepEqual(ui.disabled(label), [false], label)
|
||||
assert.ok(!ui.text().includes('Für diesen Eintrag läuft noch eine Anfrage.'))
|
||||
await ui.click('Ich kümmere mich') // Anfrage zu e1 läuft
|
||||
assert.equal(api.calls.length, 1)
|
||||
// der erste Brief sperrt sich selbst (wie bisher), der Hinweis erscheint dort nicht: die Sperre ist die eigene
|
||||
assert.deepEqual(ui.disabled('Erledigt'), [true]); assert.ok(!ui.text().includes('Für diesen Eintrag läuft noch eine Anfrage.'))
|
||||
// ein zweiter Eintrag kann währenddessen bearbeitet werden (eigene Id)
|
||||
await ui.close(); await ui.open(1)
|
||||
await ui.click('Ich kümmere mich')
|
||||
assert.deepEqual(api.calls.map((c) => c[0]), ['e1', 'e2'])
|
||||
finish({ item: { $id: 'e1' } }); await settle()
|
||||
await ui.close(); await ui.open(0)
|
||||
assert.deepEqual(ui.disabled('Erledigt'), [false]) // Anfrage zu e1 ist zu Ende
|
||||
} finally { ui.end() }
|
||||
})
|
||||
|
||||
test('Pult (bedient, P4-T32): ein „unsicher“-Eintrag ohne Entwurf öffnet „Als Mensch antworten“ mit leerem Feld', async () => {
|
||||
const api = scriptedApi()
|
||||
const ui = await startList([{ ...unsicher, draft: undefined }], api)
|
||||
|
||||
Reference in new issue
Block a user