Workers P3-Endprüfung W8: wiederkehrende Bedienelemente im Pult mit eindeutigem Namen
"Details", "Anzeige öffnen", das Entwurfsfeld und die Aktionsgruppe tragen den Titel der Zeile im
zugänglichen Namen ("Details zu <Titel>"), das sichtbare Wort steht vorn (WCAG 2.5.3); ohne
Titel gilt der schlichte Name. Der Prüfstand sucht die Knöpfe unter den neuen Namen und prüft
zusätzlich die Eindeutigkeit der Namen (W8) und die Abschlusszeile im Reiter Erledigt (W5).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4ec3022df4
commit
17fb02150e
3 files changed
+70
-10
No files matched your search
@@ -317,7 +317,7 @@ test('PultList (gerendert): Aktionen je Art und Status, Fremdtext nur als Text,
|
||||
let html = show([{ ...base, originalText: 'Original <img src=x onerror=alert(1)>', draft: 'Hallo <script>alert(1)</script>', title: 'T <b>x</b>' }])
|
||||
for (const t of ['Kopieren & öffnen', 'Ich kümmere mich', 'Als gesendet markieren', 'Verwerfen', 'Details', '66640 Namborn · Score 72', 'vor 3 Std.']) assert.ok(html.includes(t), t)
|
||||
const erledigt = '<button class="btn" type="button">Erledigt</button>' // der Filter „Erledigt“ steht ebenfalls auf der Seite: nur den Knopf der Zeile meinen
|
||||
assert.ok(!html.includes(erledigt)); assert.match(html, /<a class="link" href="https:\/\/www\.kleinanzeigen\.de\/s-anzeige\/x\/1-2-3" target="_blank" rel="noopener noreferrer">/)
|
||||
assert.ok(!html.includes(erledigt)); assert.match(html, /<a class="link" href="https:\/\/www\.kleinanzeigen\.de\/s-anzeige\/x\/1-2-3" target="_blank" rel="noopener noreferrer" aria-label="Anzeige öffnen: T <b>x<\/b>">/)
|
||||
assert.match(html, /<textarea class="textarea wk-pult-draft"[^>]*>Hallo <script>alert\(1\)<\/script><\/textarea>/)
|
||||
// Fremdtext erscheint nie als Markup
|
||||
assert.ok(!html.includes('<script>') && !html.includes('<img') && !html.includes('<b>x</b>')); assert.ok(html.includes('Original <img src=x onerror=alert(1)>'))
|
||||
@@ -386,3 +386,36 @@ test('PultList (gerendert): abgeschlossene Einträge zeigen Ergebnis, Person und
|
||||
assert.ok(open.includes('<span>vor 4 Tagen</span>')); assert.ok(!open.includes('Gesendet')); assert.ok(!open.includes('badge green'))
|
||||
} finally { delete globalThis.__pultFeed; delete globalThis.__pultEmployees }
|
||||
})
|
||||
|
||||
// Endprüfung P3 (W8): „Details“, „Anzeige öffnen“, Entwurfsfeld und Aktionsgruppe tragen den Titel der Zeile im zugänglichen Namen
|
||||
test('PultList (gerendert): wiederkehrende Bedienelemente haben je Zeile einen eigenen zugänglichen Namen, sichtbares Wort vorn (W8)', async () => {
|
||||
const { render } = await loadList()
|
||||
const show = (items) => {
|
||||
globalThis.__pultFeed = { items, loading: false, error: null, refresh: async () => {} }
|
||||
globalThis.__pultEmployees = []
|
||||
return render({ api: {}, me: { id: 'u1', name: 'Justin' } })
|
||||
}
|
||||
const base = { kind: 'plattform_antwort', status: 'offen', draft: 'Hallo', createdAt: new Date().toISOString(), sourceUrl: 'https://www.kleinanzeigen.de/s-anzeige/x/1-2-3', prospect: { $id: 'p1', name: 'Verein' } }
|
||||
try {
|
||||
const html = show([{ ...base, $id: 'a', title: 'Suche Webdesigner' }, { ...base, $id: 'b', title: 'Homepage für Handwerker <b>x</b> & "Co"' }])
|
||||
for (const name of ['Details zu Suche Webdesigner', 'Anzeige öffnen: Suche Webdesigner', 'Entwurf der Antwort: Suche Webdesigner', 'Aktionen: Suche Webdesigner']) {
|
||||
assert.ok(html.includes(`aria-label="${name}"`), name)
|
||||
}
|
||||
// zwei Zeilen ⇒ zwei verschiedene Namen; Fremdtext im Namen ist als Attribut kodiert
|
||||
const names = [...html.matchAll(/aria-label="(Details zu [^"]*)"/g)].map((m) => m[1])
|
||||
assert.equal(names.length, 2); assert.equal(new Set(names).size, 2)
|
||||
assert.ok(html.includes('aria-label="Details zu Homepage für Handwerker <b>x</b> & "Co""'))
|
||||
assert.ok(!html.includes('<b>x</b>'))
|
||||
// das sichtbare Wort bleibt (WCAG 2.5.3) und steht im Namen vorn
|
||||
assert.match(html, /aria-label="Details zu Suche Webdesigner">Details<\/button>/)
|
||||
assert.match(html, /aria-label="Anzeige öffnen: Suche Webdesigner">Anzeige öffnen<\/a>/)
|
||||
// leerer oder fehlender Titel: schlichter Name, nie „zu undefined“
|
||||
for (const title of ['', ' ', undefined]) {
|
||||
const bare = show([{ ...base, $id: 'c', title }])
|
||||
assert.ok(!bare.includes('undefined'), String(title))
|
||||
assert.ok(!bare.includes('Details zu'), String(title)); assert.ok(!bare.includes('Anzeige öffnen:'), String(title))
|
||||
assert.ok(bare.includes('aria-label="Entwurf der Antwort"'), String(title)); assert.ok(bare.includes('aria-label="Aktionen"'), String(title))
|
||||
assert.match(bare, />Details<\/button>/)
|
||||
}
|
||||
} finally { delete globalThis.__pultFeed; delete globalThis.__pultEmployees }
|
||||
})
|
||||
Reference in new issue
Block a user