================================================================================ DANH SÁCH 49 KỊCH BẢN KIỂM THỬ - LARAVEL DUSK BROWSER TESTS Dự án: Quay Số May Mắn - quayso.sisvietnam.vn Tổng kết: 49 tests PASSED | 90 assertions | ~103 giây ================================================================================ -------------------------------------------------------------------------------- FILE 1: tests/Browser/ExampleTest.php (1 test) -------------------------------------------------------------------------------- [TC-01] test_basic_example Mô tả : Kiểm tra cơ bản trang chủ tải được vòng quay may mắn. Bước : 1. Truy cập URL gốc "/". Kết quả: Phần tử #wheelCanvas (canvas vòng quay) hiển thị trên trang. -------------------------------------------------------------------------------- FILE 2: tests/Browser/GamePageTest.php (12 tests) -------------------------------------------------------------------------------- [TC-02] test_game_page_loads_when_guest Mô tả : Trang game tải được khi người dùng chưa đăng nhập. Bước : 1. Truy cập "/game" với vai trò khách (guest). Kết quả: URL path là "/game" (trang không bị redirect). [TC-03] test_root_redirects_to_game Mô tả : URL gốc "/" hiển thị cùng nội dung với "/game". Bước : 1. Truy cập "/". Kết quả: Phần tử #wheelCanvas (canvas vòng quay) hiển thị. [TC-04] test_game_page_shows_lucky_wheel_canvas Mô tả : Canvas vòng quay may mắn hiển thị trên trang game. Bước : 1. Truy cập "/game". Kết quả: Phần tử #wheelCanvas hiển thị trong trang. [TC-05] test_spin_button_is_present Mô tả : Nút "Quay" hiển thị trên trang game. Bước : 1. Truy cập "/game". Kết quả: Phần tử #spinButton hiển thị trong trang. [TC-06] test_game_rule_ribbon_is_present Mô tả : Banner "Thể lệ tham dự" hiển thị trên trang game. Bước : 1. Truy cập "/game". Kết quả: Phần tử #game_rule hiển thị trong trang. [TC-07] test_guest_sees_login_prompt_on_game Mô tả : Khách chưa đăng nhập nhìn thấy thông báo yêu cầu đăng nhập. Bước : 1. Đăng xuất ("/logout"). 2. Truy cập "/game". Kết quả: Thông báo ".alert_wheel_spin" hiển thị; Link đăng nhập (href chứa "login") hiển thị. [TC-08] test_logged_in_user_can_see_spin_button_enabled Mô tả : Người dùng đã đăng nhập và chưa quay thấy nút quay ở trạng thái sẵn sàng. Bước : 1. Đăng xuất và vào "/login". 2. Nhập thông tin cá nhân (họ tên, SĐT mới, địa chỉ, nguồn biết SIS, nghề nghiệp). 3. Nhấn "Gửi thông tin" và chờ redirect về "/game". Kết quả: Thuộc tính data-check của #spinButton = "true" (nút quay được bật). Dọn dẹp: Xóa user vừa tạo khỏi DB. [TC-09] test_already_spined_user_sees_spin_button_disabled Mô tả : Người dùng đã quay (spined=1) thấy nút quay bị khóa. Chuẩn bị: Tạo user với spined=1 trực tiếp trong DB. Bước : 1. Đăng nhập bằng user có spined=1. 2. Truy cập "/game". Kết quả: Thuộc tính data-check của #spinButton = "false" (nút quay bị khóa). Dọn dẹp: Xóa user test khỏi DB. [TC-10] test_game_rule_popup_loads Mô tả : Popup thể lệ tham dự tải nội dung khi nhấn banner. Bước : 1. Truy cập "/game". 2. Xóa các element ".alert" bằng JavaScript (để không che banner). 3. Nhấn vào #game_rule bằng JavaScript click. 4. Chờ 800ms. Kết quả: Phần tử #gamerule (popup) hiển thị trong trang. [TC-11] test_game_rule_api_returns_html Mô tả : API /game/rule trả về nội dung HTML (dùng cho AJAX). Bước : 1. Truy cập "/game/rule" trực tiếp trên trình duyệt. Kết quả: Source HTML của trang chứa chuỗi "class=" (là fragment HTML hợp lệ). [TC-12] test_checkspined_returns_error_for_guest Mô tả : API /checkspined trả lỗi khi người dùng chưa đăng nhập. Bước : 1. Đăng xuất ("/logout"). 2. Truy cập "/checkspined". Kết quả: Trang hiển thị chuỗi "error". [TC-13] test_checkspined_returns_zero_for_new_user Mô tả : API /checkspined trả spined=0 cho người dùng mới chưa quay. Chuẩn bị: Tạo user mới với spined=0 trong DB. Bước : 1. Đăng nhập bằng user đó. 2. Truy cập "/checkspined". Kết quả: Trang hiển thị chuỗi '"spined":0'. Dọn dẹp: Xóa user test khỏi DB. -------------------------------------------------------------------------------- FILE 3: tests/Browser/CreateAccountTest.php (5 tests) -------------------------------------------------------------------------------- [TC-14] test_login_page_shows_form Mô tả : Trang đăng ký/đăng nhập hiển thị đủ các trường nhập liệu. Bước : 1. Đăng xuất để đảm bảo trạng thái guest. 2. Truy cập "/login". Kết quả: Tiêu đề "Nhập thông tin cá nhân" hiển thị; Các trường input[name="name"], input[name="phone"], input[name="address"], input[name="job"] đều có mặt.ss [TC-15] test_empty_form_shows_validation_errors Mô tả : Gửi form rỗng phải hiện lỗi validation từ server. Bước : 1. Đăng xuất và truy cập "/login". 2. Nhấn "Gửi thông tin" mà không nhập gì. 3. Chờ phần tử ".text-danger" xuất hiện. Kết quả: Ít nhất một phần tử ".text-danger" (thông báo lỗi) hiển thị. [TC-16] test_invalid_phone_shows_error Mô tả : Số điện thoại sai định dạng phải hiện thông báo lỗi. Bước : 1. Truy cập "/login". 2. Nhập tên hợp lệ, nhập SĐT = "12345" (sai định dạng). 3. Điền các trường còn lại và nhấn "Gửi thông tin". Kết quả: Trang hiển thị "Số điện thoại không đúng định dạng". [TC-17] test_successful_registration_redirects_to_game Mô tả : Đăng ký thành công tạo tài khoản mới và chuyển về trang game. Bước : 1. Truy cập "/login". 2. Nhập: tên="Test Dusk User", SĐT=số ngẫu nhiên (09xxxxxxxx), địa chỉ="Cần Thơ", nguồn biết SIS=1, nghề nghiệp="Kỹ sư". 3. Nhấn "Gửi thông tin" và chờ thông báo "thành công". Kết quả: URL path là "/game" (đăng ký thành công, redirect về game). DB Check: User có phone tương ứng tồn tại trong DB; name = "TEST DUSK USER" (đã uppercase); address = "Cần Thơ"; known_sis = 1; job = "Kỹ sư"; email = "@phone.local"; spined = 0; status = 1. Dọn dẹp: Xóa user test khỏi DB. [TC-18] test_authenticated_user_sees_account_page Mô tả : Người dùng đã đăng nhập truy cập /login sẽ thấy trang tài khoản của họ. Bước : 1. Đăng ký tài khoản mới (SĐT ngẫu nhiên). 2. Sau khi đăng nhập, truy cập lại "/login". Kết quả: Trường phone được điền sẵn số điện thoại của người dùng (chứng tỏ đang hiển thị form cập nhật tài khoản, không phải form đăng ký). DB Check: User tồn tại; spined = 0; status = 1. Dọn dẹp: Xóa user test khỏi DB. -------------------------------------------------------------------------------- FILE 4: tests/Browser/AccountManagementTest.php (5 tests) -------------------------------------------------------------------------------- [TC-19] test_update_account_successfully Mô tả : Người dùng cập nhật thông tin tài khoản thành công. Bước : 1. Đăng ký và đăng nhập tài khoản mới. 2. Truy cập "/login" (trang tài khoản). 3. Xóa và nhập lại: tên="Tên Mới Test", địa chỉ="Hà Nội", nguồn biết SIS=0, nghề nghiệp="Giáo viên". 4. Nhấn "Cập nhật" và chờ thông báo "thành công". Kết quả: URL path là "/game" (cập nhật thành công). DB Check: name = "TÊN MỚI TEST" (đã uppercase); address = "Hà Nội"; known_sis = 0; job = "Giáo viên". Dọn dẹp: Xóa user test khỏi DB. [TC-20] test_update_account_with_empty_name_shows_error Mô tả : Cập nhật tài khoản với tên rỗng phải hiện lỗi validation. Bước : 1. Đăng ký và đăng nhập tài khoản mới. 2. Truy cập "/login", xóa trường tên. 3. Nhấn "Cập nhật". Kết quả: Phần tử ".text-danger" (thông báo lỗi) hiển thị. [TC-21] test_update_account_with_invalid_phone_shows_error Mô tả : Cập nhật tài khoản với số điện thoại sai định dạng phải hiện lỗi. Bước : 1. Đăng ký và đăng nhập tài khoản mới. 2. Truy cập "/login", xóa và nhập SĐT = "abcde". 3. Nhấn "Cập nhật". Kết quả: Trang hiển thị "Số điện thoại không đúng định dạng". [TC-22] test_history_section_visible_when_authenticated Mô tả : Phần lịch sử hoạt động hiển thị khi người dùng đã đăng nhập. Bước : 1. Đăng ký và đăng nhập tài khoản mới. 2. Truy cập "/login" (trang tài khoản). Kết quả: Trang hiển thị "LỊCH SỬ HOẠT ĐỘNG". [TC-23] test_logout_works Mô tả : Đăng xuất thành công xóa session người dùng. Bước : 1. Đăng ký và đăng nhập tài khoản mới. 2. Truy cập "/logout". Kết quả: Người dùng ở trạng thái guest (assertGuest). -------------------------------------------------------------------------------- FILE 5: tests/Browser/AdminLoginTest.php (7 tests) -------------------------------------------------------------------------------- Chuẩn bị chung: Trước mỗi test tạo admin user với đầy đủ roles trong DB. Dọn dẹp chung: Sau mỗi test xóa UserRole và admin user khỏi DB. [TC-24] test_admin_login_page_shows_form Mô tả : Trang quản trị "/admin" hiển thị form đăng nhập. Bước : 1. Truy cập "/admin". Kết quả: Các trường input[name="email"], input[name="password"], input[type="submit"] đều hiển thị. [TC-25] test_admin_login_with_wrong_credentials_shows_error Mô tả : Đăng nhập admin với thông tin sai phải hiện thông báo lỗi. Bước : 1. Truy cập "/admin". 2. Nhập email="wrong@email.com", password="wrongpassword". 3. Nhấn "Login". Kết quả: Phần tử ".alert-danger" (hoặc tương đương) hiển thị. [TC-26] test_admin_login_with_empty_fields_shows_validation Mô tả : Gửi form đăng nhập admin rỗng phải hiện lỗi validation server-side. Bước : 1. Truy cập "/admin". 2. Dùng JavaScript xóa thuộc tính "required" khỏi tất cả input (để bypass validation HTML5 của trình duyệt). 3. Nhấn "Login" mà không nhập gì. Kết quả: Phần tử ".text-danger" hoặc ".alert-danger" hiển thị. [TC-27] test_admin_login_successful Mô tả : Đăng nhập admin thành công và chuyển vào trang quản lý. Bước : 1. Đăng xuất admin ("/admin/logout"). 2. Truy cập "/admin", nhập email và password đúng. 3. Nhấn "Login" và chờ redirect. Kết quả: URL path là "/admin/account" (đăng nhập thành công). [TC-28] test_authenticated_admin_visiting_login_sees_form Mô tả : Admin đã đăng nhập truy cập "/admin" vẫn thấy form login (không redirect). Bước : 1. Đăng nhập bằng loginAs(adminUser). 2. Truy cập "/admin". Kết quả: URL path vẫn là "/admin"; form input[name="email"] hiển thị. [TC-29] test_unauthenticated_access_to_admin_account_redirects Mô tả : Truy cập trang admin khi chưa đăng nhập bị redirect về trang login. Bước : 1. Đăng xuất admin. 2. Truy cập "/admin/account" trực tiếp. Kết quả: URL path là "/admin" (bị redirect về trang đăng nhập admin). [TC-30] test_admin_logout Mô tả : Đăng xuất admin thành công — sau đó không thể vào trang quản lý. Bước : 1. Đăng xuất admin (clear session cũ). 2. Đăng nhập thực qua form với email/password đúng. 3. Chờ redirect vào "/admin/account". 4. Đăng xuất qua "/logout" (frontend route). 5. Truy cập "/admin/account". Kết quả: URL path là "/admin" (bị redirect về login, xác nhận đã logout). Lưu ý : Dùng đăng nhập form thực (không dùng loginAs) để tránh Dusk tự động re-authenticate sau khi logout. -------------------------------------------------------------------------------- FILE 6: tests/Browser/AdminPrizeTest.php (9 tests) -------------------------------------------------------------------------------- Chuẩn bị chung: Tạo admin user với đầy đủ roles trong DB. Dọn dẹp chung: Xóa UserRole và admin user khỏi DB. [TC-31] test_prize_list_page_loads Mô tả : Trang danh sách giải thưởng tải thành công. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/prizes". Kết quả: Phần tử "table" hoặc ".table" hiển thị. [TC-32] test_add_prize_form_loads Mô tả : Trang thêm mới giải thưởng hiển thị đầy đủ form. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/prize/update?id=0". Kết quả: Các trường input[name="prize_name"], input[name="prize_order"], select[name="prize_status"] đều hiển thị. [TC-33] test_add_prize_with_empty_name_shows_error Mô tả : Gửi form thêm giải thưởng với tên rỗng phải hiện lỗi validation. Bước : 1. Đăng nhập admin, vào "/admin/prize/update?id=0". 2. Dùng JavaScript xóa thuộc tính "required" của các input. 3. Nhấn "Thêm mới" mà không nhập tên. Kết quả: Phần tử ".text-danger", ".alert-danger" hoặc tương đương hiển thị. [TC-34] test_create_prize_successfully Mô tả : Thêm mới giải thưởng thành công và dữ liệu được lưu vào DB. Bước : 1. Đăng nhập admin, vào "/admin/prize/update?id=0". 2. Nhập: prize_name=tên ngẫu nhiên, prize_number=100, prize_order=99, prize_status=1. 3. Nhấn "Thêm mới" và chờ ".alert-success". Kết quả: Thông báo thành công hiển thị. DB Check: Prize với tên vừa nhập tồn tại trong DB; prize_status = 1; prize_number = 100; prize_order = 99. Dọn dẹp: Xóa prize test khỏi DB. [TC-35] test_update_prize_successfully Mô tả : Cập nhật tên giải thưởng thành công. Chuẩn bị: Tạo prize "Dusk Prize To Update" trực tiếp trong DB. Bước : 1. Đăng nhập admin, vào "/admin/prize/update?id={prizeId}". 2. Xóa và nhập tên mới vào prize_name. 3. Nhấn "Cập nhật" và chờ ".alert-success". Kết quả: Thông báo thành công hiển thị. DB Check: Prize::find(id)->prize_name bằng tên mới vừa nhập. Dọn dẹp: Xóa prize test khỏi DB. [TC-36] test_delete_prize_successfully Mô tả : Xóa giải thưởng thành công khỏi hệ thống. Chuẩn bị: Tạo prize "Dusk Prize To Delete" trực tiếp trong DB. Bước : 1. Đăng nhập admin, vào "/admin/prizes". 2. Truy cập "/admin/prize/delete/{prizeId}" trực tiếp. 3. Chờ 1000ms (hệ thống redirect sau khi xóa). Kết quả: Prize::find(prizeId) trả về null (đã bị xóa khỏi DB). [TC-37] test_prize_winner_list_loads Mô tả : Trang danh sách người trúng giải tải thành công. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/prizeuser". Kết quả: Phần tử "table" hoặc ".table" hiển thị. [TC-38] test_prize_winner_list_has_date_filter Mô tả : Trang danh sách người trúng giải có bộ lọc theo ngày. Bước : 1. Đăng nhập admin, truy cập "/admin/prizeuser". Kết quả: Phần tử #fromDateTime và #toDateTime hiển thị. [TC-39] test_prize_winner_export_link_present Mô tả : Trang danh sách người trúng giải có nút/link xuất Excel. Bước : 1. Đăng nhập admin, truy cập "/admin/prizeuser". Kết quả: Phần tử #excel_export hiển thị. -------------------------------------------------------------------------------- FILE 7: tests/Browser/AdminUserTest.php (5 tests) -------------------------------------------------------------------------------- Chuẩn bị chung: Tạo admin user (với đầy đủ roles) và target user trong DB. Dọn dẹp chung: Xóa UserRole, admin user và target user khỏi DB. [TC-40] test_user_list_page_loads Mô tả : Trang danh sách người dùng trong admin tải thành công. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/users". Kết quả: Phần tử "table" hoặc ".table" hiển thị. [TC-41] test_user_list_shows_target_user Mô tả : User mới tạo xuất hiện trong danh sách quản lý người dùng. Bước : 1. Truy vấn DB: User với status != '' (điều kiện của controller). 2. Đăng nhập admin, truy cập "/admin/users", chờ #table. Kết quả: Target user tồn tại trong query DB (email khớp); Bảng #table hiển thị trên trang. Lưu ý : DataTables có phân trang; dùng DB assertion thay vì tìm kiếm text trực tiếp trên trình duyệt. [TC-42] test_edit_user_form_shows_existing_data Mô tả : Form cập nhật user điền sẵn thông tin hiện tại. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/users/update?id={targetUserId}". Kết quả: Trường input "name" có giá trị = tên hiện tại của user; Trường input "email" có giá trị = email hiện tại của user. [TC-43] test_update_user_name_successfully Mô tả : Admin cập nhật tên người dùng thành công (không uppercase). Bước : 1. Đăng nhập admin, vào "/admin/users/update?id={targetUserId}". 2. Xóa và nhập tên mới = "Updated Dusk Name". 3. Nhấn "Cập nhật" và chờ ".alert-success". Kết quả: Thông báo thành công hiển thị. DB Check: User::find(id)->name = "Updated Dusk Name" (Admin controller KHÔNG uppercase tên, khác với frontend controller). [TC-44] test_admin_account_page_shows_user_info Mô tả : Trang tài khoản admin hiển thị đúng thông tin người dùng đang đăng nhập. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/account". Kết quả: Trường input "email" có giá trị = email của admin đang đăng nhập. -------------------------------------------------------------------------------- FILE 8: tests/Browser/AdminParameterTest.php (5 tests) -------------------------------------------------------------------------------- Chuẩn bị chung: Tạo admin user với đầy đủ roles trong DB. Dọn dẹp chung: Xóa UserRole và admin user khỏi DB. [TC-45] test_parameter_page_loads Mô tả : Trang cấu hình hệ thống (parameter) tải thành công. Bước : 1. Đăng nhập admin. 2. Truy cập "/admin/parameter". Kết quả: Phần tử "form" hiển thị trong trang. [TC-46] test_parameter_page_shows_game_rule_field Mô tả : Trang cấu hình có trường nhập "Thể lệ tham dự" (game_rule). Bước : 1. Đăng nhập admin, truy cập "/admin/parameter". Kết quả: Phần tử [name="game_rule"] hoặc textarea hiển thị. [TC-47] test_update_game_rule_successfully Mô tả : Cập nhật nội dung thể lệ tham dự thành công và lưu vào DB. Chuẩn bị: Đọc và lưu giá trị game_rule hiện tại từ DB. Bước : 1. Đăng nhập admin, truy cập "/admin/parameter". 2. Dùng JavaScript gán giá trị mới vào [name="game_rule"] (hỗ trợ cả CKEditor nếu có). 3. Nhấn "Cập nhật" và chờ ".alert-success". Kết quả: Thông báo thành công hiển thị. DB Check: Parameter với key="game_rule" tồn tại; parameter_value chứa chuỗi vừa nhập (assertStringContainsString). Dọn dẹp: Khôi phục giá trị game_rule gốc trong DB. [TC-48] test_parameter_page_has_image_upload_fields Mô tả : Trang cấu hình có trường upload ảnh logo. Bước : 1. Đăng nhập admin, truy cập "/admin/parameter". Kết quả: Phần tử input[type="file"][name="logo_image"] hoặc input[name="logo_image"] hiển thị. [TC-49] test_parameter_page_requires_auth Mô tả : Truy cập "/admin/parameter" khi chưa đăng nhập bị redirect. Bước : 1. Đăng xuất admin ("/admin/logout"). 2. Truy cập "/admin/parameter" trực tiếp. Kết quả: URL path là "/admin" (bị redirect về trang đăng nhập admin). ================================================================================ TỔNG KẾT ================================================================================ Số file test : 8 files Số test cases : 49 test cases Số assertions : 90 assertions Thời gian : ~103 giây Kết quả : ALL PASSED ✓ Phân bổ theo chức năng: ┌──────────────────────────────────────────┬────────┐ │ Chức năng │ Tests │ ├──────────────────────────────────────────┼────────┤ │ ExampleTest (sanity check) │ 1 │ │ Trang game & API vòng quay │ 12 │ │ Đăng ký tài khoản │ 5 │ │ Quản lý tài khoản người dùng │ 5 │ │ Đăng nhập / đăng xuất admin │ 7 │ │ Quản lý giải thưởng (admin) │ 9 │ │ Quản lý người dùng (admin) │ 5 │ │ Cấu hình hệ thống (admin) │ 5 │ ├──────────────────────────────────────────┼────────┤ │ TỔNG CỘNG │ 49 │ └──────────────────────────────────────────┴────────┘ Công nghệ kiểm thử: - Framework : Laravel Dusk v8.5 (Browser Automation Testing) - Browser : Google Chrome 146 (non-snap, /usr/bin/google-chrome) - Driver : ChromeDriver 146 - Môi trường : WSL2 + WSLg, DUSK_HEADLESS_DISABLED=true - Server : php artisan serve --port=8001 - DB : MySQL (fsg3kct926qj_quaysoDB) ================================================================================