feat: Add Playwright end-to-end testing setup and initial test suites for various application flows.

This commit is contained in:
supalerk-ar66 2026-03-02 16:26:22 +07:00
parent 9bc24fbe8a
commit a3b2e55443
50 changed files with 3321 additions and 101 deletions

View file

@ -9,8 +9,8 @@
ควบคุมการทำงานและการนำทาง (Routing) ของผู้ใช้งานแต่ละหน้า โดยจะเรียกใช้ `components/` และ `composables/` มาทำงานร่วมกัน
- **`pages/index.vue` (หน้า Landing Page):**
- **หน้าที่:** หน้าแรกสุดของระบบสำหรับผู้เยี่ยมชม (Guest) นำเสนอคอร์สเด่นและจุดเด่นของระบบ
- **การเชื่อมโยง:** ใช้ Layout `landing`, เชื่อมต่อ `useCourse`, `useCategory` และ components เช่น `CourseCard`, `LandingHeader`, `LandingFooter`
- **หน้าที่:** หน้าแรกสุดของระบบสำหรับผู้เยี่ยมชม นำเสนอคอร์สเด่น รายละเอียดสถิติ และรีวิวล่าสุด โดยดึงข้อมูลจริงจาก API (Dynamic Data) ขับเคลื่อน UI ทันสมัย
- **การเชื่อมโยง:** ใช้ Layout `landing`, เชื่อมต่อ `useCourse`, `useCategory` และ components พื้นฐานเช่น `CourseCard`, `LandingHeader`, `LandingFooter`, `StarIcon`, และ `NuxtTime`
- **`pages/auth/` (กลุ่มหน้าเข้าสู่ระบบและสมัครสมาชิก):**
- **`login.vue`:** หน้าเข้าสู่ระบบ (เชื่อม `useAuth` -> `login()`)
- **`register.vue`:** หน้าลงทะเบียนผู้ใช้ใหม่ (เชื่อม `useAuth` -> `register()`)
@ -34,12 +34,12 @@
---
## 2. 🧩 ตัวจัดการตรรกะและข้อมูล (Composables Directory: `composables/`)
## 2. 🧩 ตัวจัดการข้อมูล (Composables Directory: `composables/`)
เปรียบเสมือน "สมอง" ของระบบ แยกการจัดการข้อมูล (State) และการเรียก API (Fetch) ออกจากหน้าจอ (UI)
- **`useAuth.ts`:**
- **หน้าที่:** จัดการ Login, Register, Logout, ระบบ Token (Access & Refresh), ดึง Data ของผู้ใช้
- **หน้าที่:** จัดการ Login, Register, Request Reset Password, อัปโหลดรูปโปรไฟล์ (Avatar), ระบบ Token (มีกลไก Refresh Token อัตโนมัติเมื่อพบ 401), และดึง/อัปเดตข้อมูลผู้ใช้
- **ถูกเรียกใช้โดย:** แทบทุกหน้าจอและ `middleware/auth.ts`
- **`useCourse.ts`:**
- **หน้าที่:** ศูนย์รวม API คอร์สเรียน (ดึงรายการคอร์ส, รายละเอียด, รายชื่อบทเรียน, การลงทะเบียน, ส่งความคืบหน้า, โหลดหน้าวิดีโอ)
@ -96,7 +96,7 @@
### ภาพรวมการหมุนเวียนข้อมูล (Data Flow Example)
1. **ล็อกอิน:** หน้า `login.vue` กดยืนยัน -> เรียก `useAuth.login()` -> ได้ Token และ Role ยัดลง Local Cache (Cookie)
1. **ล็อกอินและจัดการ Session:** หน้า `login.vue` กดยืนยัน -> เรียก `useAuth.login()` -> ได้ Token และรายละเอียดผู้ใช้ยัดลง Cookie -> _หากดึงโปรไฟล์แล้ว API หมดอายุ (401)_ ระบบจะเรียก `refreshAccessToken()` อัตโนมัติเพื่อใช้ต่อ
2. **เข้าห้องเรียน:** หน้า `index.vue` กดคอร์ส -> ส่งเข้า `middleware/auth.ts` เช็คผ่านเข้าหน้าเรียน -> `pages/course/[id].vue` เรียก `useCourse.fetchCourseById(id)` -> ส่งข้อมูลให้ UI
3. **เปิดคลิปเรียน:** `learning.vue` ส่ง URL ให้ `<VideoPlayer />` เล่น
4. **บันทึกเวลาเรียน:** `VideoPlayer` เฝ้าดูเวลา (TimeUpdate) -> รายงานตัวเลขกลับมายังฟังก์ชัน `handleVideoTimeUpdate()` ที่อยู่ใน `learning.vue` -> เรียก `useCourse.saveVideoProgress()` ส่ง API กลับ Database
4. **บันทึกเวลาเรียน:** `VideoPlayer` เฝ้าดูเวลา (TimeUpdate) -> รายงานตัวเลขกลับมายังบัญชีผู้ใช้ใน `learning.vue` -> เรียก `useCourse.saveVideoProgress()` ส่ง API กลับ Database พร้อมเช็คสถานะเนื้อหาว่าสำเร็จหรือไม่

View file

@ -3,7 +3,7 @@
เอกสารฉบับนี้สรุปรายละเอียดทางเทคนิค โครงสร้างโค้ด และกลไกการทำงานของระบบ **Frontend-Learner (ฝั่งผู้เรียน)**
ใช้เป็นคู่มือสำหรับการพัฒนา บำรุงรักษา และขยายระบบต่อไป
> อัปเดตล่าสุด: 27 กุมภาพันธ์ 2026 (อัปเดตคอมเมนต์ภาษาไทย & แก้ไข TypeScript)
> อัปเดตล่าสุด: 2 มีนาคม 2026 (อัปเดตระบบแปลภาษา UI & ปรับปรุงหน้า Landing Page เป็น Dynamic Data)
---
@ -39,10 +39,9 @@
### 1.2 Security & Authentication
- **Token Management:** ใช้ JWT (Access & Refresh Tokens) จัดเก็บผ่าน `useCookie`
โดยตั้งค่าความปลอดภัยระดับ **HTTP-only** และ **SameSite**
โดยมีกลไกสกัดจับ (Interceptors) ภายใน `useAuth` เช่นเมื่อโหลดโปรไฟล์หรือ **อัปโหลดรูปภาพ** หากโดน API ดีดกลับสถานะ 401 จะทำการต่ออายุ (Refresh) Token อัตโนมัติทันที
- **Middleware:** `auth.ts` ตรวจสอบสิทธิ์การเข้าถึงหน้า Dashboard และ Classroom แบบ Real-time
- **Persistence:** ระบบ Remember Me (จดจำอีเมล) ใช้ `localStorage` แยกส่วนจาก Session
เพื่อความปลอดภัยและสะดวกสำหรับผู้ใช้
- **Persistence:** ระบบ Remember Me (จดจำอีเมล) และธีมจัดเก็บผ่าน `localStorage` แยกวงจรจาก Session (จะไม่ลบหายไปตอนสั่ง Logout)
---
@ -123,6 +122,7 @@
ที่จำสถานะตามผู้ใช้งาน
- **Interactive Quizzes:** ระบบสอบที่สลับคำถามอัตโนมัติ พร้อมโหมดเฉลย (Answer Review) ที่ชัดเจน
- **Certificate Automation:** ระบบตรวจสอบสิทธิ์ความสำเร็จและออกใบประกาศนียบัตรได้ทันที
- **Dynamic Landing Page:** หน้าแรกเชื่อมต่อข้อมูลจริงจาก API ครบถ้วน (คอร์สเรียน, รีวิว) ขจัดข้อมูล Mock-up รกๆ ออก ใช้คอมโพเนนต์เสริมที่สร้างเองเช่น `StarIcon` ควบคู่กับ `@nuxt/time` เพื่อจัดฟอร์แมตวันที่แบบมือโปร
---
@ -166,7 +166,7 @@ _(หมายเหตุ: Nuxt จะอ่านค่า `NUXT_PUBLIC_API_BA
ระบบมี 2 รูปแบบการแปลภาษาคือ:
- **UI Elements แบบ Static:** แปลผ่านไฟล์หรือแท็กในระบบ `@nuxtjs/i18n` (การสลับภาษาทำผ่านแฮมเบอร์เกอร์เมนูด้านบนขวา แจ้งสถานะผ่าน `useI18n()`)
- **UI Elements แบบ Static:** แปลผ่านไฟล์หรือแท็กในระบบ `@nuxtjs/i18n` อย่างสมบูรณ์ (เช่น Component `AppHeader` ที่รองรับการสลับภาษา, ข้อความบอกโหมด Light/Dark, และชื่อสิทธิ์ User Roles จะถูกเรียกใช้ผ่าน i18n keys ทั้งหมดโดยไม่มีการ Hardcode)
- **API Content แบบ Dynamic:** ในตาราง Course หรือ Quiz จากหลังบ้าน จะใช้โครงสร้างแบบคู่ (เช่น `title: { th: "...", en: "..." }`) โดยในทุกตรรกะหน้าเรียน (Composables) จะมีฟังก์ชันช่วยอย่าง `getLocalizedText()` ไว้คอยแปลงก้อน JSON นี้เป็นภาษาที่ผู้ใช้เลือกในปัจจุบันอัตโนมัติ
---