跳至主要内容

US-001: 用戶登入 - 手動測試指南

測試日期: ____________ 測試人員: ____________ 測試環境: npm run dev (localhost:3000)


測試前準備

1. 啟動開發伺服器

npm run dev

2. 測試帳號

系統預設的測試帳號(參考 src/mocks/data/seeds.ts):

角色用戶名密碼
店主owner@florist.comPassword123!
店員staff@florist.comPassword123!
設計師designer@florist.comPassword123!
送貨員delivery@florist.comPassword123!

測試場景

✅ Scenario 1: 使用有效憑證登入成功(正常流程)

目標: 驗證完整的登入流程

操作步驟

  1. 訪問登入頁面

    • 在瀏覽器訪問 http://localhost:3000/login
    • ✅ 驗證: 看到品牌識別區(Logo 圖示、「花店管理系統」標題)
    • ✅ 驗證: 看到登入表單卡片(歡迎文字、用戶名、密碼、記住我、登入按鈕)
    • ✅ 驗證: 開發環境下看到測試帳號提示(藍色 info 區塊)
  2. 輸入有效憑證

    • 用戶名:staff@florist.com(或直接點擊測試帳號提示)
    • 密碼:Password123!
    • 不勾選「記住我」
  3. 測試密碼顯示切換

    • 點擊密碼欄位右側的眼睛圖示(👁)
    • ✅ 驗證: 密碼從圓點顯示變為明文顯示
    • ✅ 驗證: 圖示從 Eye 變為 EyeOff
    • 再次點擊切換回密碼模式
  4. 提交登入

    • 點擊「登入」按鈕
    • ✅ 驗證: 按鈕顯示 spinner + 「登入中...」文字
    • ✅ 驗證: 按鈕在載入期間為 disabled 狀態
  5. 驗證登入成功

    • ✅ 驗證: 看到 Toast 通知「登入成功!」(綠色)
    • ✅ 驗證: 約 500ms 後頁面重定向至首頁 /
    • ✅ 驗證: Header 右上角顯示用戶資訊(頭像、姓名)
    • ✅ 驗證: Application Launcher 可用(根據角色顯示對應 Applet)
    • ✅ 驗證: URL 位於首頁(不在登入頁面)
  6. 檢查 Token 儲存

    • 打開瀏覽器開發者工具 (F12) → Application/儲存空間
    • ✅ 驗證: Redux DevTools 中可見 iam.me.authorization.access_token
    • ✅ 驗證: Console 沒有錯誤訊息
  7. 檢查審計日誌

    • 打開 Console 頁籤
    • ✅ 驗證: 看到類似以下日誌:
      [AUDIT] Login successful: staff@florist.com (role: ROLE_SALES)

預期結果

  • ✅ 登入成功
  • ✅ Toast 通知顯示
  • ✅ Token 正確儲存
  • ✅ 頁面重定向
  • ✅ 用戶資訊正確顯示
  • ✅ 審計日誌記錄

✅ Scenario 2: 使用錯誤密碼登入失敗

目標: 驗證錯誤密碼的處理

操作步驟

  1. 訪問 http://localhost:3000/login
  2. 輸入用戶名:staff@florist.com
  3. 輸入錯誤密碼:WrongPassword123
  4. 點擊「登入」按鈕
  5. ✅ 驗證: 看到錯誤訊息「用戶名或密碼錯誤」
  6. ✅ 驗證: 用戶名欄位保留輸入值
  7. ✅ 驗證: 密碼欄位保留輸入值(方便用戶修改錯字)
  8. ✅ 驗證: 仍停留在登入頁面
  9. ✅ 驗證: 未儲存 access_token(檢查 localStorage)

預期結果

  • ✅ 顯示錯誤訊息
  • ✅ 表單狀態正確
  • ✅ 未發放 Token

✅ Scenario 3: 使用不存在的用戶名登入失敗

目標: 驗證不存在的用戶處理(防止用戶枚舉攻擊)

操作步驟

  1. 訪問 http://localhost:3000/login
  2. 輸入不存在的用戶名:nonexistent@example.com
  3. 輸入任意密碼:Password123!
  4. 點擊「登入」按鈕
  5. ✅ 驗證: 看到錯誤訊息「用戶名或密碼錯誤」(與 Scenario 2 相同)
  6. ✅ 驗證: 錯誤訊息不洩漏用戶是否存在

預期結果

  • ✅ 錯誤訊息與錯誤密碼相同
  • ✅ 不洩漏用戶存在資訊

✅ Scenario 4: 使用「記住我」功能登入

目標: 驗證「記住我」功能(Token 儲存位置與有效期)

安全設計說明:

  • 勾選記住我 → Token 存 localStorage(關閉瀏覽器後保留,適合個人電腦)
  • 不勾選 → Token 存 sessionStorage(關閉瀏覽器即清除,適合公用電腦)

操作步驟

  1. 勾選「記住我」登入

    • 訪問 http://localhost:3000/login
    • 輸入用戶名:staff@florist.com
    • 輸入密碼:Password123!
    • 勾選「記住我」
    • 點擊「登入」按鈕
    • ✅ 驗證: 登入成功
  2. 檢查 Token 儲存位置

    • 打開 DevTools → Application → Storage
    • ✅ 驗證: localStorage 中有 access_tokenrefresh_token
    • ✅ 驗證: localStorageauth_storage_type = local
    • ✅ 驗證: sessionStorage沒有 token
  3. 關閉瀏覽器後重新開啟

    • 完全關閉瀏覽器(非只關閉分頁)
    • 重新開啟瀏覽器,訪問 http://localhost:3000
    • ✅ 驗證: 仍保持登入狀態(不需重新登入)
  4. 登出後測試「不勾選記住我」

    • 點擊右上角用戶選單 → 「登出」
    • 重新登入,這次不勾選「記住我」
    • ✅ 驗證: sessionStorage 中有 access_tokenrefresh_token
    • ✅ 驗證: localStorageauth_storage_type = session
    • ✅ 驗證: localStorage沒有 access_token
  5. 關閉瀏覽器後驗證自動登出

    • 完全關閉瀏覽器
    • 重新開啟瀏覽器,訪問 http://localhost:3000
    • ✅ 驗證: 已自動登出,重定向至登入頁面

預期結果

  • ✅ 勾選記住我 → Token 存 localStorage,關閉瀏覽器後保留
  • ✅ 不勾選 → Token 存 sessionStorage,關閉瀏覽器自動登出
  • ✅ Refresh Token 有效期:勾選 30 天 / 不勾選 7 天

✅ Scenario 5: 登入失敗 5 次後帳號鎖定

目標: 驗證 Rate Limiting 機制

操作步驟

  1. 連續輸入錯誤密碼 5 次

    • 訪問 http://localhost:3000/login
    • 輸入用戶名:staff@florist.com
    • 輸入錯誤密碼:WrongPassword
    • 點擊「登入」(重複 5 次)
  2. 驗證帳號鎖定

    • ✅ 驗證: 第 5 次失敗後,看到錯誤訊息「帳號已被鎖定,請 15 分鐘後再試」
    • ✅ 驗證: 錯誤訊息顯示為紅色警告框
  3. 嘗試使用正確密碼登入

    • 輸入用戶名:staff@florist.com
    • 輸入正確密碼Password123!
    • 點擊「登入」
    • ✅ 驗證: 仍然看到「帳號已被鎖定」錯誤訊息
    • ✅ 驗證: 無法登入
  4. 檢查審計日誌

    • 打開 Console
    • ✅ 驗證: 看到類似以下日誌:
      [AUDIT] Account locked: staff@florist.com (5 failed attempts)
  5. 等待 15 分鐘後重試(可選)

    • 等待 15 分鐘(或修改系統時間)
    • 再次嘗試登入
    • ✅ 驗證: 可以成功登入

預期結果

  • ✅ 5 次失敗後帳號鎖定
  • ✅ 鎖定期間無法登入
  • ✅ 審計日誌記錄
  • ✅ 15 分鐘後自動解鎖

✅ Scenario 6: 表單驗證 - 必填欄位為空

目標: 驗證前端表單驗證

操作步驟

  1. 訪問 http://localhost:3000/login
  2. 不填寫任何欄位,直接點擊「登入」按鈕
  3. ✅ 驗證: 用戶名欄位顯示錯誤訊息「請輸入用戶名」
  4. ✅ 驗證: 密碼欄位顯示錯誤訊息「請輸入密碼」
  5. ✅ 驗證: 錯誤欄位顯示紅色邊框
  6. ✅ 驗證: 未發送 API 請求(檢查 Network 面板)

預期結果

  • ✅ 前端驗證攔截空欄位
  • ✅ 顯示清晰的錯誤訊息
  • ✅ 未發送 API 請求

✅ Scenario 7: 鍵盤操作(無障礙性)

目標: 驗證鍵盤導航功能

操作步驟

  1. 訪問 http://localhost:3000/login

  2. 使用 Tab 鍵導航

    • 按 Tab → 焦點移至用戶名欄位
    • ✅ 驗證: 用戶名欄位顯示焦點指示(藍色邊框)
    • 按 Tab → 焦點移至密碼欄位
    • ✅ 驗證: 密碼欄位顯示焦點指示
    • 按 Tab → 焦點移至「記住我」勾選框
    • 按 Tab → 焦點移至「登入」按鈕
  3. 使用 Enter 鍵提交

    • 在用戶名欄位輸入 staff@florist.com
    • 按 Tab 移至密碼欄位
    • 輸入密碼 Password123!
    • 按 Enter 鍵
    • ✅ 驗證: 表單提交(與點擊按鈕效果相同)

預期結果

  • ✅ Tab 鍵導航順序正確
  • ✅ 焦點指示清晰
  • ✅ Enter 鍵可提交表單

✅ Scenario 8: 響應式設計(手機版)

目標: 驗證手機版佈局

操作步驟

  1. 打開開發者工具 (F12)
  2. 切換至裝置模擬模式(Device Toolbar)
  3. 選擇「iPhone SE」或「iPhone 12 Pro」
  4. 訪問 http://localhost:3000/login
  5. ✅ 驗證: 表單在手機螢幕正常顯示
  6. ✅ 驗證: 按鈕大小適合手指點擊(至少 44x44px)
  7. ✅ 驗證: 文字清晰可讀(字體不會太小)
  8. ✅ 驗證: 沒有橫向捲軸

預期結果

  • ✅ 手機版佈局正確
  • ✅ 可用性良好

✅ Scenario 9: 已登入用戶訪問登入頁面

目標: 驗證重定向邏輯

操作步驟

  1. 先完成登入(參考 Scenario 1)
  2. ✅ 驗證: 已在首頁 /
  3. 在瀏覽器網址列輸入 http://localhost:3000/login
  4. ✅ 驗證: 自動重定向至首頁 /(不顯示登入表單)

預期結果

  • ✅ 已登入用戶無法訪問登入頁面
  • ✅ 自動重定向至首頁

✅ Scenario 10: 登出功能

目標: 驗證登出邏輯

操作步驟

  1. 先完成登入(參考 Scenario 1)
  2. 點擊右上角用戶選單
  3. ✅ 驗證: 看到下拉選單(個人設定、登出)
  4. 點擊「登出」
  5. ✅ 驗證: 重定向至登入頁面 /login
  6. 打開開發者工具 → Application/儲存空間
  7. ✅ 驗證: localStorage 中的 access_token 已清除
  8. 嘗試訪問受保護頁面(如 /orders
  9. ✅ 驗證: 自動重定向至登入頁面

預期結果

  • ✅ 登出成功
  • ✅ Token 已清除
  • ✅ 無法訪問受保護頁面

測試檢查清單

完成所有測試場景後,請勾選以下項目:

基本功能

  • Scenario 1: 有效憑證登入成功
  • Scenario 2: 錯誤密碼登入失敗
  • Scenario 3: 不存在的用戶名登入失敗
  • Scenario 4: 記住我功能
  • Scenario 5: 帳號鎖定機制
  • Scenario 6: 表單驗證(空欄位)
  • Scenario 7: 鍵盤操作
  • Scenario 8: 響應式設計
  • Scenario 9: 已登入用戶重定向
  • Scenario 10: 登出功能

UI/UX

  • 表單佈局清晰易懂
  • 錯誤訊息顯示在正確位置
  • 載入狀態顯示正確(按鈕顯示「登入中...」)
  • 響應式設計(桌面、手機)
  • DaisyUI 語義色彩正確應用
  • 焦點指示清晰(Tab 導航)

安全性

  • 密碼欄位不顯示明文
  • 錯誤訊息不洩漏用戶存在資訊
  • Rate Limiting 正常運作(5 次失敗鎖定)
  • Token 儲存位置正確(localStorage)
  • 審計日誌記錄正確

API

  • POST /api/v1/auth/login 正常運作
  • 錯誤響應格式正確
  • Console 審計日誌記錄正確

已知問題

記錄測試過程中發現的問題:





測試結論

  • 測試通過: ☐ 是 / ☐ 否
  • 備註: ___________________________________________________________
  • 測試人員簽名: ________________ 日期: ________________

最後更新: 2025-12-10