fix: keep password form visible on validation error
The password setup/change form used hx-target="#password-section" with hx-swap="innerHTML", but that div wraps the form itself. On a validation error the route returns only an alert div, so the swap replaced the entire form — the password inputs disappeared. Most visible during registration's "set password" step. Retarget the form to a dedicated #password-error div outside the form (mirrors the working login form's #login-error pattern), so the form and its inputs survive errors while messages still render inside #password-section. Also fix pre-existing broken e2e tests: they omitted the required current_password fill and used passwords below the zxcvbn strength threshold (score 1 < MIN_PASSWORD_STRENGTH=2). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fb133f9cba
commit
bcfe3a2a15
3 changed files with 26 additions and 6 deletions
|
|
@ -42,6 +42,7 @@ test.describe('Credentials page', () => {
|
|||
|
||||
test.describe('Password validation', () => {
|
||||
test('shows mismatch error', async ({ page }) => {
|
||||
await page.fill('#current_password', fixtures.cred_password);
|
||||
await page.fill('#password', 'newpassword1');
|
||||
await page.fill('#confirm', 'newpassword2');
|
||||
await page.click('#password-section button[type="submit"]');
|
||||
|
|
@ -51,6 +52,23 @@ test.describe('Credentials page', () => {
|
|||
await expect(alert).toContainText('do not match');
|
||||
});
|
||||
|
||||
test('keeps the password form visible after a validation error', async ({ page }) => {
|
||||
await page.fill('#current_password', fixtures.cred_password);
|
||||
await page.fill('#password', 'newpassword1');
|
||||
await page.fill('#confirm', 'newpassword2');
|
||||
await page.click('#password-section button[type="submit"]');
|
||||
|
||||
const alert = page.locator('#password-section [role="alert"]');
|
||||
await expect(alert).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Regression: the form and its inputs must NOT disappear on error.
|
||||
await expect(page.locator('#password')).toBeVisible();
|
||||
await expect(page.locator('#confirm')).toBeVisible();
|
||||
await expect(
|
||||
page.locator('#password-section button[type="submit"]'),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test('password input has minlength="8"', async ({ page }) => {
|
||||
await expect(page.locator('#password')).toHaveAttribute('minlength', '8');
|
||||
});
|
||||
|
|
@ -62,8 +80,9 @@ test.describe('Credentials page', () => {
|
|||
|
||||
test.describe('Password change', () => {
|
||||
test('succeeds with matching passwords', async ({ page }) => {
|
||||
await page.fill('#password', 'newpassword123');
|
||||
await page.fill('#confirm', 'newpassword123');
|
||||
await page.fill('#current_password', fixtures.cred_password);
|
||||
await page.fill('#password', 'purple-tiger-mountain-42');
|
||||
await page.fill('#confirm', 'purple-tiger-mountain-42');
|
||||
await page.click('#password-section button[type="submit"]');
|
||||
|
||||
const status = page.locator('#password-section [role="status"]');
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ test.describe('Full user journey', () => {
|
|||
await expect(passwordInput).toBeVisible();
|
||||
await expect(confirmInput).toBeVisible();
|
||||
|
||||
await passwordInput.fill('mypassword123');
|
||||
await confirmInput.fill('mypassword123');
|
||||
await passwordInput.fill('purple-tiger-mountain-42');
|
||||
await confirmInput.fill('purple-tiger-mountain-42');
|
||||
await page.click('#password-section button[type="submit"]');
|
||||
|
||||
// Wait for success message
|
||||
|
|
@ -51,7 +51,7 @@ test.describe('Full user journey', () => {
|
|||
|
||||
// ---- Step 4: Login with the password we just set ----
|
||||
await page.fill('#username', fixtures.register_username);
|
||||
await page.fill('#password', 'mypassword123');
|
||||
await page.fill('#password', 'purple-tiger-mountain-42');
|
||||
await page.click('form[hx-post="/login/password"] button[type="submit"]');
|
||||
|
||||
// Wait for redirect to credentials page
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue