Removes pressFirstButton; the web build now exposes real button nodes. Refs #41 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
102 lines
4.7 KiB
TypeScript
102 lines
4.7 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
import { subjects } from '../../support/auth-config';
|
|
import { expireConfirmationLink, expireRecoveryLink } from '../../support/db';
|
|
import { GoTrueClient, randomEmail, randomPassword } from '../../support/gotrue';
|
|
import { expectMailCount, extractTokenHash, waitForMail } from '../../support/mailpit';
|
|
import { freshBrowserContext, fillField, open, t, textOf } from '../../support/web';
|
|
|
|
const gotrue = new GoTrueClient();
|
|
|
|
async function requestReset(page: import('@playwright/test').Page, email: string) {
|
|
await open(page, '/forgot-password');
|
|
await fillField(page.getByRole('textbox', { name: 'Email address' }), email);
|
|
await page.getByRole('button', { name: 'Send link' }).click();
|
|
await expect(page).toHaveURL(/\/forgot-password\/check-email$/);
|
|
}
|
|
|
|
test.describe('KTO-01 Kriterium 8 (web): Passwort zuruecksetzen', () => {
|
|
test('KTO-01 Kriterium 8: Reset anfordern, Link oeffnen, neues Passwort setzen, mit neuem Passwort anmelden', async ({ page }) => {
|
|
const email = randomEmail();
|
|
const oldPassword = randomPassword();
|
|
const newPassword = randomPassword();
|
|
await gotrue.createConfirmedUser(email, oldPassword);
|
|
|
|
await requestReset(page, email);
|
|
const mail = await waitForMail(email);
|
|
expect(mail.Subject).toBe(subjects.recovery.en);
|
|
const { link, type } = extractTokenHash(mail);
|
|
expect(type).toBe('recovery');
|
|
|
|
// Der Link fuehrt auf die Link-Seite; erst der Klick loest die Pruefung aus.
|
|
await open(page, link.pathname + link.search);
|
|
await page.getByRole('button', { name: t.recoverySubmit }).click();
|
|
await expect(page).toHaveURL(/\/reset-password$/);
|
|
|
|
await fillField(page.getByRole('textbox', { name: 'New password' }), newPassword);
|
|
await page.getByRole('button', { name: 'Save password' }).click();
|
|
await expect(textOf(page, t.passwordChanged)).toBeVisible();
|
|
|
|
expect((await gotrue.signIn(email, newPassword)).status).toBe(200);
|
|
expect((await gotrue.signIn(email, oldPassword)).body.error_code).toBe('invalid_credentials');
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: bereits benutzter Reset-Link zeigt „abgelaufen oder schon benutzt“', async ({ page }) => {
|
|
const email = randomEmail();
|
|
await gotrue.createConfirmedUser(email, randomPassword());
|
|
await gotrue.recover(email);
|
|
const { link, tokenHash } = extractTokenHash(await waitForMail(email));
|
|
expect((await gotrue.verify(tokenHash, 'recovery')).status).toBe(200); // Link verbraucht
|
|
|
|
await open(page, link.pathname + link.search);
|
|
await page.getByRole('button', { name: t.recoverySubmit }).click();
|
|
await expect(textOf(page, t.linkInvalid)).toBeVisible();
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: AUTH-CFG-07 abgelaufener Reset-Link (recovery_sent_at 1 h + 1 s zurueck) zeigt den Fehlerzustand', async ({ page }) => {
|
|
const email = randomEmail();
|
|
await gotrue.createConfirmedUser(email, randomPassword());
|
|
await gotrue.recover(email);
|
|
const { link } = extractTokenHash(await waitForMail(email));
|
|
await expireRecoveryLink(email);
|
|
|
|
await open(page, link.pathname + link.search);
|
|
await page.getByRole('button', { name: t.recoverySubmit }).click();
|
|
await expect(textOf(page, t.linkInvalid)).toBeVisible();
|
|
await expect(page.getByRole('button', { name: 'Request a new link' })).toBeVisible();
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: AUTH-CFG-07 abgelaufener Bestaetigungslink zeigt den Fehlerzustand', async ({ page }) => {
|
|
const email = randomEmail();
|
|
await gotrue.signUp(email, randomPassword());
|
|
const { link } = extractTokenHash(await waitForMail(email));
|
|
await expireConfirmationLink(email);
|
|
|
|
await open(page, link.pathname + link.search);
|
|
await page.getByRole('button', { name: t.confirmSubmit }).click();
|
|
await expect(textOf(page, t.linkInvalid)).toBeVisible();
|
|
});
|
|
|
|
test('KTO-01 Kriterium 8: Link ohne Parameter zeigt sofort den Fehlerzustand', async ({ page }) => {
|
|
await open(page, '/auth/confirm');
|
|
await expect(textOf(page, t.linkInvalid)).toBeVisible();
|
|
});
|
|
|
|
test('KTO-01 Kriterium 4/8: Reset fuer unbekannte Adresse zeigt denselben Bildschirm, es geht keine Mail raus', async ({ page, browser }) => {
|
|
const known = randomEmail();
|
|
await gotrue.createConfirmedUser(known, randomPassword());
|
|
await requestReset(page, known);
|
|
await expect(textOf(page, /reset link if an account exists/)).toBeVisible();
|
|
const body = (await page.locator('body').ariaSnapshot()).trim();
|
|
|
|
const unknown = randomEmail('unknown');
|
|
const ctx = await freshBrowserContext(browser);
|
|
try {
|
|
const other = await ctx.newPage();
|
|
await requestReset(other, unknown);
|
|
expect((await other.locator('body').ariaSnapshot()).trim()).toBe(body);
|
|
} finally {
|
|
await ctx.close();
|
|
}
|
|
await expectMailCount(unknown, 0);
|
|
});
|
|
});
|