Shuffle/e2e/tests/web/krit49-anmeldung-einstieg.spec.ts
cschlaefke f078c8a094 feat(auth): sign-in prompt card on the home screen for signed-out users
Adds SignInPrompt (sign in / create account), showSignInPromptProvider,
HomeScreen as ConsumerWidget, l10n de/en, widget/unit tests and a
Playwright web test (#49 criterion 1, QUE-09 criterion 13, QUE-06).

Refs #49

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 01:03:16 +01:00

78 lines
3.6 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { GoTrueClient, randomEmail, randomPassword } from '../../support/gotrue';
import { expectSignedIn, login, open, textOf } from '../../support/web';
const gotrue = new GoTrueClient();
/** Texte (app_en.arb). */
const prompt = {
title: 'Your account',
body: 'Sign in to manage your collection and games.',
};
test.describe('#49 Kriterium 1 / QUE-09 Kriterium 13 (web): Anmelde-Hinweis auf der Startseite', () => {
test('#49 Kriterium 1: abgemeldet zeigt die Startseite den Hinweis mit „Sign in“ und „Create account“', async ({ page }) => {
await open(page, '/');
await expect(textOf(page, prompt.title)).toBeVisible();
await expect(textOf(page, prompt.body)).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign in', exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: 'Create account', exact: true })).toBeVisible();
});
test('#49 Kriterium 1: „Sign in“ fuehrt zu /login', async ({ page }) => {
await open(page, '/');
await page.getByRole('button', { name: 'Sign in', exact: true }).click();
await expect(page).toHaveURL(/\/login$/);
await expect(page.getByRole('textbox', { name: 'Email address' })).toBeVisible();
});
test('#49 Kriterium 1: „Create account“ fuehrt zu /register', async ({ page }) => {
await open(page, '/');
await page.getByRole('button', { name: 'Create account', exact: true }).click();
await expect(page).toHaveURL(/\/register$/);
await expect(page.getByRole('textbox', { name: 'Display name' })).toBeVisible();
});
test('QUE-06 Kriterium 4: Lesereihenfolge; erster Tab erreicht „Sign in“, Enter loest aus', async ({ page }) => {
await open(page, '/');
await expect(page.getByRole('button', { name: 'Sign in', exact: true })).toBeVisible();
// Lesereihenfolge (Semantics-Baum): Ueberschrift, Text, „Sign in“, „Create account“.
const snapshot = await page.locator('body').ariaSnapshot();
const pos = [
`heading "${prompt.title}"`,
prompt.body,
'button "Sign in"',
'button "Create account"',
].map((needle) => snapshot.indexOf(needle));
expect(pos.every((p) => p >= 0)).toBe(true);
expect([...pos].sort((x, y) => x - y)).toEqual(pos);
// Flutter-Web behandelt Tab im eigenen Fokussystem; `document.activeElement` bleibt auf dem
// Semantics-Platzhalter. Deshalb wird die Reihenfolge ueber das Verhalten geprueft: erster Tab
// = „Sign in“, zweiter Tab = „Create account“, Enter loest den fokussierten Knopf aus.
// Der Fokusring selbst wird im Canvas gezeichnet (Widget-Test, Theme).
await page.keyboard.press('Tab');
await page.keyboard.press('Enter');
await expect(page).toHaveURL(/\/login$/);
});
test('QUE-06 Kriterium 4: zweiter Tab erreicht „Create account“, Enter loest aus', async ({ page }) => {
await open(page, '/');
await expect(page.getByRole('button', { name: 'Create account', exact: true })).toBeVisible();
await page.keyboard.press('Tab');
await page.keyboard.press('Tab');
await page.keyboard.press('Enter');
await expect(page).toHaveURL(/\/register$/);
});
test('#49 Kriterium 1: angemeldet erscheint der Hinweis nicht', async ({ page }) => {
const email = randomEmail();
const password = randomPassword();
await gotrue.createConfirmedUser(email, password);
await login(page, email, password);
await expectSignedIn(page);
await expect(page.getByRole('button', { name: 'Create account', exact: true })).toHaveCount(0);
await expect(textOf(page, prompt.body)).toHaveCount(0);
});
});