From 59a99ca3957edd383c3b16a98258fea175a8b097 Mon Sep 17 00:00:00 2001 From: ChayaphonKultanon Date: Sun, 16 Nov 2025 19:57:31 +0700 Subject: [PATCH] seperate test case --- src/e2e/registration.spec.ts | 120 ++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/src/e2e/registration.spec.ts b/src/e2e/registration.spec.ts index f5489f0..0a7ab63 100644 --- a/src/e2e/registration.spec.ts +++ b/src/e2e/registration.spec.ts @@ -6,157 +6,159 @@ function uniqueEmail() { } test.describe('Registration Flow', () => { - test('TC1-1: happy path with validation checks', async ({ page }) => { - // Intercept registration API to avoid depending on backend state - await page.route('**/api/v1/auth/register', async (route) => { - route.fulfill({ status: 200, body: JSON.stringify({ success: true }) }); - }); - - // Start at email page + // TC1-1: Invalid Email (missing @) + test('TC1-1: invalid email shows browser validation', async ({ page }) => { await page.goto('/registration/email'); - - // Try invalid email const emailInput = page.getByTestId('registration-email-input'); await emailInput.fill('invalid'); await page.getByTestId('registration-email-next-btn').click(); - // Assert native browser validation message (Thai locale as in UI) const validationMessage = await emailInput.evaluate((el) => (el as HTMLInputElement).validationMessage); await expect(validationMessage).toContain("Please include an '@' in the email address. 'invalid' is missing an '@'."); + }); - // Enter valid email - const email = uniqueEmail(); - await page.getByTestId('registration-email-input').fill(email); + // TC1-2: Valid Email + test('TC1-2: valid email navigates to name step', async ({ page }) => { + await page.goto('/registration/email'); + await page.getByTestId('registration-email-input').fill('example@gmail.com'); await page.getByTestId('registration-email-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/name$/); + }); - // Name step - leave blank to trigger errors + // TC1-3: Empty First/Last Name + test('TC1-3: empty names show validation', async ({ page }) => { + await page.goto('/registration/name'); await page.getByTestId('registration-name-next-btn').click(); - await expect(page.getByText("First name must be at least 2 characters")).toBeVisible(); - await expect(page.getByText("Last name must be at least 2 characters")).toBeVisible(); + await expect(page.getByText('First name must be at least 2 characters')).toBeVisible(); + await expect(page.getByText('Last name must be at least 2 characters')).toBeVisible(); + }); - // Fill names + // TC1-4: Valid Name + test('TC1-4: valid names navigate to password step', async ({ page }) => { + await page.goto('/registration/name'); await page.getByTestId('registration-first-name-input').fill('John'); await page.getByTestId('registration-last-name-input').fill('Doe'); await page.getByTestId('registration-name-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/password$/); + }); - // Password step - mismatch first + // TC1-5: Passwords not match + test('TC1-5: passwords mismatch shows error', async ({ page }) => { + await page.goto('/registration/password'); await page.getByTestId('registration-password-input').fill('StrongPass1!'); await page.getByTestId('registration-confirm-password-input').fill('Different1!'); await page.getByTestId('registration-password-next-btn').click(); await expect(page.getByText('Passwords not match')).toBeVisible(); + }); - // Correct confirm password + // TC1-6: Strong Password (passes all) -> Terms + test('TC1-6: strong password navigates to terms', async ({ page }) => { + await page.goto('/registration/password'); + await page.getByTestId('registration-password-input').fill('StrongPass1!'); await page.getByTestId('registration-confirm-password-input').fill('StrongPass1!'); await page.getByTestId('registration-password-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/terms$/); + }); - // Terms step - Next disabled until checked + // TC1-7: Terms not accepted + test('TC1-7: terms next disabled until accepted', async ({ page }) => { + await page.goto('/registration/terms'); const nextBtn = page.getByTestId('registration-terms-next-btn'); await expect(nextBtn).toBeDisabled(); + }); + + // TC1-8: Terms accepted -> Success + test('TC1-8: accept terms navigates to success', async ({ page }) => { + await page.route('**/api/v1/auth/register', async (route) => { + route.fulfill({ status: 200, body: JSON.stringify({ success: true }) }); + }); + await page.goto('/registration/terms'); + const nextBtn = page.getByTestId('registration-terms-next-btn'); await page.getByTestId('registration-terms-checkbox').check(); await expect(nextBtn).toBeEnabled(); await nextBtn.click(); - - // Success page await expect(page).toHaveURL(/.*\/registration\/success$/); await expect(page.getByTestId('registration-success-panel')).toBeVisible(); - await expect(page.getByText(/Successfully Signed Up/i)).toBeVisible(); }); - test('TC1-2: privacy policy link navigates correctly from password step', async ({ page }) => { + // TC1-9: Privacy Policy link + test('TC1-9: privacy policy link navigates', async ({ page }) => { await page.goto('/registration/password'); await page.getByTestId('registration-password-privacy-link').click(); await expect(page).toHaveURL(/.*\/registration\/privacyPolicy$/); await expect(page.getByText(/Privacy Policy/i)).toBeVisible(); }); - // New test: verify back buttons navigate correctly through the flow - test('TC1-3: back buttons navigate to previous steps', async ({ page }) => { - // Start at first step + // TC1-10: Back button behavior + test('TC1-10: back buttons navigate and retain values', async ({ page }) => { await page.goto('/registration/email'); - // Enter valid email and proceed const email = uniqueEmail(); await page.getByTestId('registration-email-input').fill(email); await page.getByTestId('registration-email-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/name$/); - // Click Back on name step -> email step await page.getByTestId('registration-name-back-btn').click(); await expect(page).toHaveURL(/.*\/registration\/email$/); - - // Proceed again to name step (email should persist) await page.getByTestId('registration-email-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/name$/); - // Fill names and go forward await page.getByTestId('registration-first-name-input').fill('John'); await page.getByTestId('registration-last-name-input').fill('Doe'); await page.getByTestId('registration-name-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/password$/); - // Back from password -> name, verify values persisted await page.getByTestId('registration-password-back-btn').click(); await expect(page).toHaveURL(/.*\/registration\/name$/); await expect(page.getByTestId('registration-first-name-input')).toHaveValue('John'); await expect(page.getByTestId('registration-last-name-input')).toHaveValue('Doe'); - // Forward again to password await page.getByTestId('registration-name-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/password$/); - // Fill matching strong password and proceed await page.getByTestId('registration-password-input').fill('StrongPass1!'); await page.getByTestId('registration-confirm-password-input').fill('StrongPass1!'); await page.getByTestId('registration-password-next-btn').click(); await expect(page).toHaveURL(/.*\/registration\/terms$/); - // Back from terms -> password await page.getByTestId('registration-terms-back-btn').click(); await expect(page).toHaveURL(/.*\/registration\/password$/); - - // (Optional) Proceed again to terms to ensure navigation still works - await page.getByTestId('registration-password-input').fill('StrongPass1!'); - await page.getByTestId('registration-confirm-password-input').fill('StrongPass1!'); - await page.getByTestId('registration-password-next-btn').click(); - await expect(page).toHaveURL(/.*\/registration\/terms$/); }); - // New test: password requirement validations - test('TC1-4: password requirement validations', async ({ page }) => { + // TC1-11: Weak Password - length fails + test('TC1-11: weak password fails length', async ({ page }) => { await page.goto('/registration/password'); await page.waitForLoadState('networkidle'); - // Sanity: requirement hints rendered await expect(page.getByTestId('registration-password-req-length')).toBeVisible(); - await expect(page.getByTestId('registration-password-req-capital')).toBeVisible(); - await expect(page.getByTestId('registration-password-req-number-symbol')).toBeVisible(); - - // Case 1: Fails length only (has capital + number) await page.getByTestId('registration-password-input').fill('A1!'); await page.getByTestId('registration-confirm-password-input').fill('A1!'); await page.getByTestId('registration-password-next-btn').click(); - await expect(page).toHaveURL(/.*\/registration\/password$/); await expect(page.getByTestId('registration-password-req-length')).toHaveClass(/text-error-main/); - await expect(page.getByTestId('registration-password-req-capital')).not.toHaveClass(/text-error-main/); - await expect(page.getByTestId('registration-password-req-number-symbol')).not.toHaveClass(/text-error-main/); + }); - // Case 2: Fails capital only + // TC1-12: Weak Password - capital fails + test('TC1-12: weak password fails capital', async ({ page }) => { + await page.goto('/registration/password'); + await page.waitForLoadState('networkidle'); + await expect(page.getByTestId('registration-password-req-capital')).toBeVisible(); await page.getByTestId('registration-password-input').fill('abcd1234!'); await page.getByTestId('registration-confirm-password-input').fill('abcd1234!'); await page.getByTestId('registration-password-next-btn').click(); - await expect(page.getByTestId('registration-password-req-length')).not.toHaveClass(/text-error-main/); await expect(page.getByTestId('registration-password-req-capital')).toHaveClass(/text-error-main/); - await expect(page.getByTestId('registration-password-req-number-symbol')).not.toHaveClass(/text-error-main/); + }); - // Case 3: Fails number/symbol only + // TC1-13: Weak Password - number/symbol fails + test('TC1-13: weak password fails number or symbol', async ({ page }) => { + await page.goto('/registration/password'); + await page.waitForLoadState('networkidle'); + await expect(page.getByTestId('registration-password-req-number-symbol')).toBeVisible(); await page.getByTestId('registration-password-input').fill('Abcdefgh'); await page.getByTestId('registration-confirm-password-input').fill('Abcdefgh'); await page.getByTestId('registration-password-next-btn').click(); - await expect(page.getByTestId('registration-password-req-length')).not.toHaveClass(/text-error-main/); - await expect(page.getByTestId('registration-password-req-capital')).not.toHaveClass(/text-error-main/); await expect(page.getByTestId('registration-password-req-number-symbol')).toHaveClass(/text-error-main/); + }); - // Case 4: All pass -> proceed to terms + // TC1-14: Strong Password (passes all) -> Terms + test('TC1-14: strong password navigates to terms', async ({ page }) => { + await page.goto('/registration/password'); await page.getByTestId('registration-password-input').fill('StrongPass1!'); await page.getByTestId('registration-confirm-password-input').fill('StrongPass1!'); await page.getByTestId('registration-password-next-btn').click();