Refactored frontend directory
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m46s
Some checks failed
Chore App Build, Test, and Push Docker Images / build-and-push (push) Failing after 2m46s
This commit is contained in:
181
frontend/e2e/mode_parent/user-profile/change-pin.spec.ts
Normal file
181
frontend/e2e/mode_parent/user-profile/change-pin.spec.ts
Normal file
@@ -0,0 +1,181 @@
|
||||
// spec: e2e/plans/user-profile.plan.md
|
||||
|
||||
import { test, expect, type APIRequestContext } from '@playwright/test'
|
||||
import { E2E_PIN } from '../../e2e-constants'
|
||||
|
||||
const BACKEND = 'http://localhost:5000'
|
||||
const NEW_PIN = '5678'
|
||||
|
||||
async function setPinDirectly(request: APIRequestContext, pin: string): Promise<void> {
|
||||
// Request a new code, retrieve it via test endpoint, verify it, then set the pin
|
||||
await request.post(`${BACKEND}/user/request-pin-setup`)
|
||||
const codeRes = await request.get(`${BACKEND}/user/e2e-get-pin-code`)
|
||||
const { code } = await codeRes.json()
|
||||
await request.post(`${BACKEND}/user/verify-pin-setup`, { data: { code } })
|
||||
await request.post(`${BACKEND}/user/set-pin`, { data: { pin } })
|
||||
}
|
||||
|
||||
test.describe('User Profile – Change Parent PIN', () => {
|
||||
test.describe.configure({ mode: 'serial' })
|
||||
|
||||
test.afterAll(async ({ request }) => {
|
||||
// Restore original PIN so subsequent test runs start fresh
|
||||
await setPinDirectly(request, E2E_PIN)
|
||||
})
|
||||
|
||||
test('Change Parent PIN link navigates to PIN setup page', async ({ page }) => {
|
||||
await page.goto('/parent/profile')
|
||||
|
||||
await page.getByRole('button', { name: 'Change Parent PIN' }).click()
|
||||
|
||||
await expect(page).toHaveURL(/\/parent\/pin-setup/)
|
||||
await expect(page.getByRole('heading', { name: 'Set up your Parent PIN' })).toBeVisible()
|
||||
})
|
||||
|
||||
test('Back from PIN setup page returns to profile', async ({ page }) => {
|
||||
// Navigate from the profile page so browser history exists
|
||||
await page.goto('/parent/profile')
|
||||
await page.getByRole('button', { name: 'Change Parent PIN' }).click()
|
||||
await expect(page).toHaveURL(/\/parent\/pin-setup/)
|
||||
|
||||
await page.goBack()
|
||||
|
||||
await expect(page).toHaveURL(/\/parent\/profile/)
|
||||
})
|
||||
|
||||
test('Send Verification Code advances to step 2', async ({ page }) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
const codeInput = page.getByPlaceholder('6-digit code')
|
||||
await expect(codeInput).toBeVisible()
|
||||
|
||||
// Verify Code is disabled while input is empty
|
||||
await expect(page.getByRole('button', { name: 'Verify Code' })).toBeDisabled()
|
||||
})
|
||||
|
||||
test('Resend Code button appears after delay', async ({ page }) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
// According to the component, resend appears after 10 seconds
|
||||
await expect(page.getByRole('button', { name: 'Resend Code' })).toBeVisible({ timeout: 15000 })
|
||||
})
|
||||
|
||||
test('Invalid code shows error', async ({ page }) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
await page.getByPlaceholder('6-digit code').fill('ZZZZZZ')
|
||||
await page.getByRole('button', { name: 'Verify Code' }).click()
|
||||
|
||||
await expect(page.getByText(/invalid code/i)).toBeVisible()
|
||||
})
|
||||
|
||||
test('Valid code advances to step 3 (Create PIN)', async ({ page, request }) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
// Retrieve the code via the test-only endpoint
|
||||
const codeRes = await request.get(`${BACKEND}/user/e2e-get-pin-code`)
|
||||
const { code } = await codeRes.json()
|
||||
|
||||
await page.getByPlaceholder('6-digit code').fill(code)
|
||||
await page.getByRole('button', { name: 'Verify Code' }).click()
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Create Parent PIN' })).toBeVisible()
|
||||
await expect(page.getByPlaceholder('New PIN')).toBeVisible()
|
||||
await expect(page.getByPlaceholder('Confirm PIN')).toBeVisible()
|
||||
await expect(page.getByRole('button', { name: 'Set PIN' })).toBeDisabled()
|
||||
})
|
||||
|
||||
test('Set PIN disabled when PINs do not match', async ({ page, request }) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
const codeRes = await request.get(`${BACKEND}/user/e2e-get-pin-code`)
|
||||
const { code } = await codeRes.json()
|
||||
await page.getByPlaceholder('6-digit code').fill(code)
|
||||
await page.getByRole('button', { name: 'Verify Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Create Parent PIN' })).toBeVisible()
|
||||
|
||||
await page.getByPlaceholder('New PIN').fill('1111')
|
||||
await page.getByPlaceholder('Confirm PIN').fill('2222')
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Set PIN' })).toBeDisabled()
|
||||
})
|
||||
|
||||
test('Set PIN disabled for fewer than 4 digits', async ({ page, request }) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
const codeRes = await request.get(`${BACKEND}/user/e2e-get-pin-code`)
|
||||
const { code } = await codeRes.json()
|
||||
await page.getByPlaceholder('6-digit code').fill(code)
|
||||
await page.getByRole('button', { name: 'Verify Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Create Parent PIN' })).toBeVisible()
|
||||
|
||||
await page.getByPlaceholder('New PIN').fill('12')
|
||||
await page.getByPlaceholder('Confirm PIN').fill('12')
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Set PIN' })).toBeDisabled()
|
||||
})
|
||||
|
||||
test('Set PIN succeeds with matching 4-digit PIN – shows success step', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
const codeRes = await request.get(`${BACKEND}/user/e2e-get-pin-code`)
|
||||
const { code } = await codeRes.json()
|
||||
await page.getByPlaceholder('6-digit code').fill(code)
|
||||
await page.getByRole('button', { name: 'Verify Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Create Parent PIN' })).toBeVisible()
|
||||
|
||||
await page.getByPlaceholder('New PIN').fill(NEW_PIN)
|
||||
await page.getByPlaceholder('Confirm PIN').fill(NEW_PIN)
|
||||
await expect(page.getByRole('button', { name: 'Set PIN' })).toBeEnabled()
|
||||
await page.getByRole('button', { name: 'Set PIN' }).click()
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Parent PIN Set!' })).toBeVisible()
|
||||
await expect(page.getByRole('button', { name: 'Back', exact: true })).toBeVisible()
|
||||
})
|
||||
|
||||
test('Back from success step exits parent mode and goes to child selector', async ({
|
||||
page,
|
||||
request,
|
||||
}) => {
|
||||
await page.goto('/parent/pin-setup')
|
||||
await page.getByRole('button', { name: 'Send Verification Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Enter Verification Code' })).toBeVisible()
|
||||
|
||||
const codeRes = await request.get(`${BACKEND}/user/e2e-get-pin-code`)
|
||||
const { code } = await codeRes.json()
|
||||
await page.getByPlaceholder('6-digit code').fill(code)
|
||||
await page.getByRole('button', { name: 'Verify Code' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Create Parent PIN' })).toBeVisible()
|
||||
|
||||
await page.getByPlaceholder('New PIN').fill(NEW_PIN)
|
||||
await page.getByPlaceholder('Confirm PIN').fill(NEW_PIN)
|
||||
await page.getByRole('button', { name: 'Set PIN' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Parent PIN Set!' })).toBeVisible()
|
||||
|
||||
await page.getByRole('button', { name: 'Back', exact: true }).click()
|
||||
|
||||
await expect(page).toHaveURL(/\/child(\/|$)/)
|
||||
// Parent mode exited – "Parent login" button visible instead of parent menu
|
||||
await expect(page.getByRole('button', { name: 'Parent login' })).toBeVisible()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user