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>
78 lines
3.6 KiB
TypeScript
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);
|
|
});
|
|
});
|