test(routes): expand register coverage for password and form branches

Adds password show/hide toggle (independent for both fields), pwHint
visible after typing, pwValid green hint for 8+ chars, pwMismatch
red hint, pwMatch green hint, form.error rendering, notifyOnMention
checkbox toggle.

7 new tests targeting ~25 branches in the register flow.

Refs #496.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-10 03:44:21 +02:00
committed by marcel
parent d1aa0dc9f0
commit 6bb520f822

View File

@@ -118,4 +118,111 @@ describe('register page', () => {
const codeInput = document.querySelector('input[name="code"]') as HTMLInputElement;
expect(codeInput.value).toBe('');
});
it('toggles password visibility when the show/hide button is clicked', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const pw = document.querySelector('input[name="password"]') as HTMLInputElement;
expect(pw.type).toBe('password');
const toggle = pw.parentElement?.querySelector('button[type="button"]') as HTMLButtonElement;
toggle.click();
await new Promise((r) => setTimeout(r, 30));
expect(pw.type).toBe('text');
toggle.click();
await new Promise((r) => setTimeout(r, 30));
expect(pw.type).toBe('password');
});
it('toggles passwordConfirm visibility independently from password', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const confirm = document.querySelector('#passwordConfirm') as HTMLInputElement;
expect(confirm.type).toBe('password');
const toggle = confirm.parentElement?.querySelector(
'button[type="button"]'
) as HTMLButtonElement;
toggle.click();
await new Promise((r) => setTimeout(r, 30));
expect(confirm.type).toBe('text');
});
it('shows the password length hint after typing a short password', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const pw = document.querySelector('input[name="password"]') as HTMLInputElement;
pw.value = 'abc';
pw.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 30));
await expect.element(page.getByText(/mindestens 8 zeichen/i)).toBeVisible();
});
it('shows the password OK hint when password is at least 8 chars', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const pw = document.querySelector('input[name="password"]') as HTMLInputElement;
pw.value = 'longenoughpw';
pw.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 30));
// password OK hint shows up — find a green-700 text near password
const greens = document.querySelectorAll('.text-green-700');
expect(greens.length).toBeGreaterThan(0);
});
it('shows the password mismatch error when confirm differs from password', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const pw = document.querySelector('input[name="password"]') as HTMLInputElement;
const confirm = document.querySelector('#passwordConfirm') as HTMLInputElement;
pw.value = 'longenoughpw';
pw.dispatchEvent(new Event('input', { bubbles: true }));
confirm.value = 'differentpw';
confirm.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 30));
const reds = document.querySelectorAll('.text-red-600');
expect(reds.length).toBeGreaterThan(0);
});
it('shows the password match success when confirm equals password', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const pw = document.querySelector('input[name="password"]') as HTMLInputElement;
const confirm = document.querySelector('#passwordConfirm') as HTMLInputElement;
pw.value = 'longenoughpw';
pw.dispatchEvent(new Event('input', { bubbles: true }));
confirm.value = 'longenoughpw';
confirm.dispatchEvent(new Event('input', { bubbles: true }));
await new Promise((r) => setTimeout(r, 30));
// At least 2 green-700 elements (pw OK + match OK)
const greens = document.querySelectorAll('.text-green-700');
expect(greens.length).toBeGreaterThanOrEqual(2);
});
it('renders the form error from the form prop', async () => {
render(RegisterPage, {
props: { data: baseData(), form: { error: 'EMAIL_TAKEN' } }
});
const errorBox = document.querySelector('.text-red-600.font-medium');
expect(errorBox).not.toBeNull();
});
it('toggles the notifyOnMention checkbox', async () => {
render(RegisterPage, { props: { data: baseData(), form: undefined } });
const cb = document.querySelector('input[name="notifyOnMention"]') as HTMLInputElement;
expect(cb.checked).toBe(true);
cb.click();
await new Promise((r) => setTimeout(r, 30));
expect(cb.checked).toBe(false);
});
});