Files
chore/frontend/vue-app/e2e/mode_parent/user-profile/delete-account.spec.ts
Ryan Kegel db6e0a7ce8
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 2m38s
feat: Implement user profile and parent profile button tests
- Added tests for user profile editing, including name changes, image uploads, and password changes.
- Implemented tests for changing the parent PIN with verification code handling.
- Created tests for account deletion with confirmation dialog and email validation.
- Introduced parent profile button tests for both temporary and permanent modes, verifying badge visibility and menu options.
- Updated Playwright configuration to include new test buckets for user profile and parent profile button scenarios.
- Added e2e plans documentation for user profile and parent profile button tests.
2026-03-18 17:20:31 -04:00

117 lines
4.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// spec: e2e/plans/user-profile.plan.md
import { test, expect } from '@playwright/test'
import { E2E_EMAIL, E2E_PASSWORD } from '../../e2e-constants'
const BACKEND = 'http://localhost:5000'
test.describe('User Profile Delete Account', () => {
test.describe.configure({ mode: 'serial' })
test.afterAll(async ({ request }) => {
// Re-seed the e2e database to restore the test user for any subsequent test suites
await request.post(`${BACKEND}/auth/e2e-seed`)
})
test('Delete My Account opens confirmation dialog', async ({ page }) => {
await page.goto('/parent/profile')
await page.getByRole('button', { name: 'Delete My Account' }).click()
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
await expect(page.locator('#confirmEmail')).toBeVisible()
await expect(page.locator('#confirmEmail')).toHaveValue('')
await expect(
page.locator('.modal-dialog').getByRole('button', { name: 'Delete', exact: true }),
).toBeDisabled()
await expect(
page.locator('.modal-dialog').getByRole('button', { name: 'Cancel' }),
).toBeVisible()
})
test('Delete button stays disabled for incomplete email', async ({ page }) => {
await page.goto('/parent/profile')
await page.getByRole('button', { name: 'Delete My Account' }).click()
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
await page.locator('#confirmEmail').fill('e2e@')
await expect(
page.locator('.modal-dialog').getByRole('button', { name: 'Delete', exact: true }),
).toBeDisabled()
})
test('Delete button enables when matching email is entered', async ({ page }) => {
await page.goto('/parent/profile')
await page.getByRole('button', { name: 'Delete My Account' }).click()
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
await page.locator('#confirmEmail').fill(E2E_EMAIL)
await expect(
page.locator('.modal-dialog').getByRole('button', { name: 'Delete', exact: true }),
).toBeEnabled()
})
test('Cancel closes the dialog without deleting the account', async ({ page }) => {
await page.goto('/parent/profile')
await page.getByRole('button', { name: 'Delete My Account' }).click()
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
await page.locator('.modal-dialog').getByRole('button', { name: 'Cancel' }).click()
// Dialog is gone, still on profile page
await expect(
page.locator('.modal-title', { hasText: 'Delete Your Account?' }),
).not.toBeVisible()
await expect(page.getByRole('heading', { name: 'User Profile' })).toBeVisible()
await expect(page).toHaveURL(/\/parent\/profile/)
})
test('Backdrop click does NOT close the delete dialog', async ({ page }) => {
await page.goto('/parent/profile')
await page.getByRole('button', { name: 'Delete My Account' }).click()
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
// Click the backdrop (outside the modal-dialog box)
await page.locator('.modal-backdrop').click({ position: { x: 10, y: 10 }, force: true })
// Dialog must still be visible the delete warning has no backdrop-click listener
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
})
test('Successful deletion: confirmation modal appears then redirects to landing page', async ({
page,
}) => {
await page.goto('/parent/profile')
await page.getByRole('button', { name: 'Delete My Account' }).click()
await expect(page.locator('.modal-title', { hasText: 'Delete Your Account?' })).toBeVisible()
await page.locator('#confirmEmail').fill(E2E_EMAIL)
await page.locator('.modal-dialog').getByRole('button', { name: 'Delete', exact: true }).click()
// Confirmation modal appears
await expect(page.locator('.modal-title', { hasText: 'Account Deleted' })).toBeVisible()
await expect(page.getByText(/marked for deletion/i)).toBeVisible()
await page.getByRole('button', { name: 'OK' }).click()
// Redirect to landing page
await expect(page).toHaveURL('/')
await expect(page.getByRole('button', { name: 'Sign In' }).first()).toBeVisible()
})
test('Login after deletion is blocked with an appropriate error', async ({ page }) => {
await page.goto('/auth/login')
await page.getByLabel('Email address').fill(E2E_EMAIL)
await page.getByLabel('Password').fill(E2E_PASSWORD)
await page.getByRole('button', { name: 'Sign in' }).click()
// Login must fail with a deletion-related error message
await expect(page.getByText(/marked for deletion/i)).toBeVisible({ timeout: 8000 })
// URL stays on the login page
await expect(page).toHaveURL(/\/auth\/login/)
})
})