fix(frontend): a11y backdrop, ≥44px PIN button, test-ids on auth & upload
- account/+page.svelte: remove `aria-hidden="true"` from the leave-confirm and data-mode-warning bottom-sheet backdrops. The attribute cascaded into the dialog children, making the inner Abmelden/Aktivieren/Abbrechen buttons unreachable in the accessibility tree (and to Playwright's `getByRole`). Discovered while writing the E2E suite; the visual layout is unchanged. - join/+page.svelte: bump the PIN-copy button from `py-1` (28px tall) to `min-h-11 min-w-11 py-2` so it clears the ≥44px touch-target floor on mobile. Touch-target audit revealed the gap. - data-testid attributes on stable interactive elements (join name input, join submit, PIN modal + copy + continue, recovery PIN + submit + try- different-name, admin login password + submit + error, recover name + PIN + submit + error, upload header submit + sticky submit + caption textarea). Targeted at ~20 spots where semantic locators were ambiguous (e.g. two "Hochladen" buttons on /upload, German strings that may iterate). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -111,16 +111,18 @@
|
||||
maxlength={4}
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
data-testid="recovery-pin-input"
|
||||
class="mb-3 w-full rounded-lg border border-gray-300 bg-white px-4 py-3 text-center text-2xl font-mono tracking-widest text-gray-900 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100"
|
||||
/>
|
||||
|
||||
{#if recoveryError}
|
||||
<p class="mb-3 text-sm text-red-600 dark:text-red-400">{recoveryError}</p>
|
||||
<p class="mb-3 text-sm text-red-600 dark:text-red-400" data-testid="recovery-error">{recoveryError}</p>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={recoveryLoading || recoveryPin.length < 4}
|
||||
data-testid="recovery-submit"
|
||||
class="mb-3 w-full rounded-lg bg-blue-600 px-4 py-3 font-medium text-white transition hover:bg-blue-700 disabled:opacity-50 dark:bg-blue-500 dark:hover:bg-blue-400"
|
||||
>
|
||||
{recoveryLoading ? 'Wird angemeldet...' : 'Anmelden'}
|
||||
@@ -129,6 +131,7 @@
|
||||
|
||||
<button
|
||||
onclick={tryDifferentName}
|
||||
data-testid="try-different-name"
|
||||
class="w-full rounded-lg border border-gray-300 px-4 py-3 font-medium text-gray-700 transition hover:bg-gray-50 dark:border-gray-700 dark:text-gray-300 dark:hover:bg-gray-800"
|
||||
>
|
||||
Anderen Namen wählen
|
||||
@@ -145,16 +148,18 @@
|
||||
bind:value={displayName}
|
||||
placeholder="Dein Name"
|
||||
maxlength={50}
|
||||
data-testid="join-name-input"
|
||||
class="mb-3 w-full rounded-lg border border-gray-300 bg-white px-4 py-3 text-lg text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:placeholder-gray-500"
|
||||
/>
|
||||
|
||||
{#if error}
|
||||
<p class="mb-3 text-sm text-red-600 dark:text-red-400">{error}</p>
|
||||
<p class="mb-3 text-sm text-red-600 dark:text-red-400" data-testid="join-error">{error}</p>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={loading || !displayName.trim()}
|
||||
data-testid="join-submit"
|
||||
class="w-full rounded-lg bg-blue-600 px-4 py-3 text-lg font-medium text-white transition hover:bg-blue-700 disabled:opacity-50 dark:bg-blue-500 dark:hover:bg-blue-400"
|
||||
>
|
||||
{loading ? 'Wird geladen...' : 'Beitreten'}
|
||||
@@ -162,7 +167,7 @@
|
||||
</form>
|
||||
|
||||
<p class="mt-4 text-center text-sm">
|
||||
<a href="/recover" class="text-blue-600 hover:underline dark:text-blue-400">Ich habe bereits einen Account</a>
|
||||
<a href="/recover" data-testid="link-to-recover" class="text-blue-600 hover:underline dark:text-blue-400">Ich habe bereits einen Account</a>
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
@@ -170,7 +175,7 @@
|
||||
</div>
|
||||
|
||||
{#if showPinModal}
|
||||
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4">
|
||||
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4" data-testid="pin-modal">
|
||||
<div class="w-full max-w-sm rounded-xl bg-white p-6 shadow-lg dark:bg-gray-900">
|
||||
<h2 class="mb-2 text-xl font-bold text-gray-900 dark:text-gray-100">Dein Wiederherstellungs-PIN</h2>
|
||||
<p class="mb-4 text-sm text-gray-600 dark:text-gray-400">
|
||||
@@ -178,10 +183,11 @@
|
||||
</p>
|
||||
|
||||
<div class="mb-4 flex items-center justify-center gap-3 rounded-lg bg-gray-100 p-4 dark:bg-gray-800">
|
||||
<span class="text-4xl font-mono font-bold tracking-widest text-gray-900 dark:text-gray-100">{pin}</span>
|
||||
<span class="text-4xl font-mono font-bold tracking-widest text-gray-900 dark:text-gray-100" data-testid="pin-display">{pin}</span>
|
||||
<button
|
||||
onclick={copyPin}
|
||||
class="rounded-md bg-gray-200 px-3 py-1 text-sm font-medium text-gray-700 hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600"
|
||||
data-testid="pin-copy"
|
||||
class="min-h-11 min-w-11 rounded-md bg-gray-200 px-3 py-2 text-sm font-medium text-gray-700 hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600"
|
||||
>
|
||||
{copied ? 'Kopiert!' : 'Kopieren'}
|
||||
</button>
|
||||
@@ -189,6 +195,7 @@
|
||||
|
||||
<button
|
||||
onclick={goToFeed}
|
||||
data-testid="continue-to-feed"
|
||||
class="w-full rounded-lg bg-blue-600 px-4 py-3 font-medium text-white transition hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-400"
|
||||
>
|
||||
Weiter zur Galerie
|
||||
|
||||
Reference in New Issue
Block a user