Báo cáo test — web-booking & app-booking
Sinh tự động từ report/build.mjs. Không sửa tay file HTML này.
Mọi con số đọc từ ledger report/cases.json và kết quả của chính lần chạy này.
252case trong ledger
251đạt
0hỏng
1lỗi đã biết
0thiếu test
0test ngoài ledger
6không phủ được
Ngân sách theo tier
48 / 2000 ms
T1 STATIC · 25 case
2525 / 12000 ms
T2 PURE · 175 case
1382 / 20000 ms
T3 DOM · 44 case
878 / 6000 ms
T4 VIEWPORT · 8 case
Ma trận độ phủ — 38 feature × 4 tier
Ánh xạ ở mức NHÓM case, không phải từng case. Ô tổng bằng 0 là feature chưa có case nào.
| Feature | Tên | T1 | T2 | T3 | T4 | Tổng |
|---|---|---|---|---|---|---|
| A1 | Trang demo: hero, điều hướng, CTA đặt lịch | 4 | · | 18 | · | 22 |
| B1 | Bước 1 — thông tin khách và thời gian | · | 32 | 18 | · | 50 |
| B2 | Chặn và báo lỗi ở bước 1 | · | 14 | 18 | · | 32 |
| B3 | Khung giờ lọc theo thời điểm hiện tại | 12 | 28 | 18 | · | 58 |
| B4 | Bước 2 — danh mục và danh sách dịch vụ | 12 | 36 | 18 | · | 66 |
| B5 | Tìm kiếm dịch vụ | · | 9 | 18 | · | 27 |
| B6 | Giỏ dịch vụ đã chọn | · | 8 | 18 | · | 26 |
| B7 | Add-on: nhóm kèm theo dịch vụ | 12 | 17 | 18 | · | 47 |
| B8 | Chặn ở tầng modal khi thiếu add-on bắt buộc | · | 17 | 18 | · | 35 |
| B9 | Chọn add-on và cộng giá | · | 39 | 18 | · | 57 |
| B10 | Chặn ở tầng đơn đặt khi rời bước 2 | · | 17 | 18 | · | 35 |
| B11 | Bước 3 — xem lại và tổng tiền | · | 20 | 18 | · | 38 |
| B12 | Ghi chú cho đơn đặt | · | · | 18 | · | 18 |
| B13 | Hộp thoại xác nhận trước thao tác xoá | · | 8 | 18 | · | 26 |
| B14 | Màn hình xác nhận thành công | · | 31 | 18 | · | 49 |
| B15 | Mobile — stepper chuyển thành 4 bước | 3 | · | · | 8 | 11 |
| B16 | Mobile — màn giỏ hàng tách riêng | 3 | · | · | 8 | 11 |
| C1 | Đăng nhập bằng số điện thoại | 12 | 19 | 7 | · | 38 |
| C2 | Nhập mã xác thực 4 ô | · | 19 | 7 | · | 26 |
| C3 | Báo lỗi khi mã chưa đủ | · | 9 | 7 | · | 16 |
| C4 | Thẻ thành viên — hạng Silver | 12 | 29 | 7 | · | 48 |
| C5 | Thẻ thành viên — hạng Gold | · | 10 | 7 | · | 17 |
| C6 | Đã đăng nhập — tự điền và hiện điểm | · | 30 | 7 | · | 37 |
| D1 | Portal — trang tổng quan | · | 8 | 14 | · | 22 |
| D2 | Portal — lịch sử đặt lịch | 12 | 10 | 14 | · | 36 |
| D3 | Portal — voucher | 12 | 6 | 14 | · | 32 |
| D4 | Portal — mã QR của voucher | 4 | 6 | 14 | · | 24 |
| D5 | Portal — danh mục đổi thưởng | 16 | 11 | 14 | · | 41 |
| D6 | Portal — đổi điểm lấy voucher tiền | · | 11 | 14 | · | 25 |
| D7 | Portal — xác nhận đổi thưởng | · | 11 | 14 | · | 25 |
| D8 | Portal — đánh giá | · | 4 | 14 | · | 18 |
| D9 | Portal — hồ sơ cá nhân | · | 2 | 14 | · | 16 |
| D10 | Portal — khung nhìn Testing | · | · | 14 | · | 14 |
| D11 | Portal — giao diện tối | · | 4 | 14 | · | 18 |
| D12 | Portal trên mobile | · | · | · | 8 | 8 |
| D13 | Portal mobile — ngăn kéo điều hướng | · | · | · | 8 | 8 |
| E1 | Portal nhúng popup qua iframe và hash | · | 11 | 5 | · | 16 |
| E2 | Lưu phiên giữa các lần tải trang | · | 11 | 5 | · | 16 |
Mọi feature đều có ít nhất một case.
Không phủ được — giới hạn của stack bun + jsdom
Sáu contract dưới đây không tier nào chứng minh được. Luôn hiển thị, không giấu.
| ID | Contract | Vì sao | Bù bằng |
|---|---|---|---|
| NC-01 | QR vẽ ra pixel quét được | jsdom: canvas.getContext trả null nếu không cài gói `canvas` | T3-PORT-05 kiểm phần tử + mã chữ; ảnh tham chiếu 27-portal-qr |
| NC-02 | Clipboard thật của hệ điều hành | jsdom không có navigator.clipboard | T2-PVCH-03 / T3-PORT-04 kiểm đúng giá trị gửi đi qua stub |
| NC-03 | Layout, kích thước, chồng lấn | jsdom không có layout engine (getComputedStyle().width trả "auto") | 37 ảnh tham chiếu trong feature-map + kiểm tay |
| NC-04 | CSS thật đổi layout ở đúng breakpoint | T4 chỉ chứng minh nhánh JS rẽ đúng | T1-BRK-02 buộc mọi ngưỡng JS có @media tương ứng |
| NC-05 | Input trusted, IME, focus thật | sự kiện tổng hợp, không phải trusted | kiểm tay theo checklist |
| NC-06 | Khác biệt WebKit ↔ Chromium | không có browser thật trong stack | kiểm tay theo checklist |
Vùng nghiệp vụ
| Vùng | Case | Đạt | Rủi ro | |
|---|---|---|---|---|
| App — huỷ lịch | 3 | 3 | medium | xem → |
| App — nhãn | 2 | 2 | low | xem → |
| App — đa ngôn ngữ | 4 | 4 | medium | xem → |
| App — đăng nhập | 3 | 3 | medium | xem → |
| Breakpoint | 3 | 3 | high | xem → |
| Danh mục dịch vụ | 9 | 9 | medium | xem → |
| Dữ liệu mẫu | 12 | 12 | medium | xem → |
| Dựng chuỗi | 10 | 10 | low | xem → |
| Giỏ dịch vụ | 8 | 8 | medium | xem → |
| Hạng thẻ | 10 | 10 | medium | xem → |
| Hợp lệ hoá | 14 | 14 | high | xem → |
| Luồng portal | 14 | 14 | medium | xem → |
| Luồng thành viên | 7 | 7 | high | xem → |
| Luồng đặt lịch | 18 | 18 | high | xem → |
| Ngày giờ | 18 | 18 | high | xem → |
| Phiên & hash | 11 | 11 | high | xem → |
| Portal — lịch hẹn | 10 | 10 | medium | xem → |
| Portal — mạng xã hội | 2 | 2 | low | xem → |
| Portal — theme | 4 | 4 | low | xem → |
| Portal — tài khoản | 4 | 4 | medium | xem → |
| Portal — voucher | 6 | 6 | medium | xem → |
| Portal — điều hướng | 4 | 4 | low | xem → |
| Portal — đánh giá | 4 | 4 | low | xem → |
| Portal — đổi thưởng | 11 | 11 | high | xem → |
| Responsive | 8 | 8 | medium | xem → |
| Ràng buộc add-on | 17 | 17 | high | xem → |
| Seam harness | 2 | 2 | high | xem → |
| Thành viên | 9 | 8 | high | xem → |
| Tiền | 12 | 12 | high | xem → |
| Toàn vẹn DOM | 3 | 3 | medium | xem → |
| Tài nguyên | 4 | 4 | high | xem → |
| Tích hợp hai file | 5 | 5 | high | xem → |
| Đa ngôn ngữ | 1 | 1 | medium | xem → |
File không test
| File | Lý do |
|---|---|
| app-booking/member-portal-v2-preinline.html | snapshot bản lặp cũ |
| app-booking/member-portal-v3-prename.html | snapshot bản lặp cũ |
| app-booking/member-portal-v4-prebook-tablet.html | snapshot bản lặp cũ |
| web-booking/huong-dan-su-dung.html | trang hướng dẫn tĩnh, không có logic |
| app-booking/huong-dan-su-dung-sona.html | trang hướng dẫn tĩnh, không có logic |
Toàn bộ case
hiện 0
| Case | Oracle | Vùng | Feature | Trạng thái | Rủi ro | ms |
|---|---|---|---|---|---|---|
| T1-BRK-01 | ngưỡng matchMedia trong JS đúng là 480px và 880px | Breakpoint | B15 B16 | đạt | high | 1 |
| T1-BRK-02 | mọi ngưỡng JS đều có @media tương ứng trong CSS | Breakpoint | B15 B16 | đạt | high | 1 |
| T1-BRK-03 | hai target dùng cùng cặp ngưỡng | Breakpoint | B15 B16 | đạt | high | 1 |
| T1-CAT-01 | SERVICES đúng 28 mục | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 1 |
| T1-CAT-02 | SERVICES không có id trùng | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 1 |
| T1-CAT-03 | mọi SERVICES.price là số không âm | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 1 |
| T1-CAT-04 | mọi SERVICES.cats nằm trong CATEGORIES — không có danh mục mồ côi | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 1 |
| T1-CAT-05 | CATEGORIES đúng 9 danh mục | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 0 |
| T1-CAT-06 | ADDONS đúng 8 mục, giá không âm | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 0 |
| T1-CAT-07 | TIERS 4 hạng, mốc 0/400/1000/2500 và tăng dần | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 0 |
| T1-CAT-08 | MEMBERS có 4 tài khoản demo, số điện thoại không trùng | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 0 |
| T1-CAT-09 | REDEEM_CATALOG 6 mục, chi phí đúng bộ giá điểm | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 14 |
| T1-CAT-10 | VOUCHERS + GIFTED_VOUCHERS: mã không trùng | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 1 |
| T1-CAT-11 | SEED_BOOKINGS 6 mục, mọi trạng thái đều được code xử lý | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 1 |
| T1-CAT-12 | INCLUDED_GROUPS: nhóm bắt buộc có min>0 và items không rỗng | Dữ liệu mẫu | B3 B4 B7 C1 C4 D2 D3 D5 | đạt | medium | 0 |
| T1-I18N-01 | bảng I18N: mọi khoá có đủ ngôn ngữ trong LANGS | Đa ngôn ngữ | — | đạt | medium | 2 |
| T1-ID-01 | mọi getElementById đều có id tồn tại trong markup hoặc do JS dựng ra | Toàn vẹn DOM | — | đạt | medium | 6 |
| T1-ID-02 | không có id trùng nhau trong markup | Toàn vẹn DOM | — | đạt | medium | 2 |
| T1-ID-03 | data-od-id không trùng nhau | Toàn vẹn DOM | — | đạt | medium | 1 |
| T1-REF-01 | mọi src/href tương đối trong markup đều trỏ tới file có thật | Tài nguyên | A1 D4 D5 | đạt | high | 1 |
| T1-REF-02 | assets/qrcode.min.js có mặt ở mọi target dùng QR | Tài nguyên | A1 D4 D5 | đạt | high | 0 |
| T1-REF-03 | 6 ảnh reward tồn tại và khớp REDEEM_CATALOG | Tài nguyên | A1 D4 D5 | đạt | high | 9 |
| T1-REF-04 | không có host ngoài nào ngoài Google Fonts đã biết | Tài nguyên | A1 D4 D5 | đạt | high | 2 |
| T1-SEAM-01 | số hàm top-level lộ ra global không tụt dưới ngưỡng | Seam harness | — | đạt | high | 1 |
| T1-SEAM-02 | số inline handler GÁN vào biến cấp trang không được tăng | Seam harness | — | đạt | high | 1 |
| T2-AAUTH-01 | authBack đưa luồng về màn nhập số điện thoại | App — đăng nhập | — | đạt | medium | 10 |
| T2-AAUTH-02 | authBack gọi nhiều lần vẫn an toàn | App — đăng nhập | — | đạt | medium | 9 |
| T2-AAUTH-03 | authResend hiện thông báo rồi tự xoá, không ném | App — đăng nhập | — | đạt | medium | 11 |
| T2-ACANCEL-01 | askCancelBooking bỏ qua lịch KHÔNG ở trạng thái sắp tới | App — huỷ lịch | — | đạt | medium | 12 |
| T2-ACANCEL-02 | doCancelBooking đổi trạng thái sang "can" | App — huỷ lịch | — | đạt | medium | 32 |
| T2-ACANCEL-03 | huỷ lại lần hai không đổi gì thêm | App — huỷ lịch | — | đạt | medium | 9 |
| T2-ACAT-01 | catLabel dịch danh mục đã biết, giữ nguyên danh mục lạ | App — nhãn | — | đạt | low | 9 |
| T2-ACAT-02 | groupLabel dịch nhóm add-on đã biết, giữ nguyên nhóm lạ | App — nhãn | — | đạt | low | 12 |
| T2-ADD-01 | groupsForService trả về nhóm khớp danh mục của dịch vụ | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 15 |
| T2-ADD-02 | dịch vụ không khớp danh mục nào thì không có nhóm bundled | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 13 |
| T2-ADD-03 | nhóm không có trường applies thì áp cho mọi dịch vụ | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 15 |
| T2-ADD-04 | hasRequiredAddons true khi dịch vụ có nhóm min>0 | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 13 |
| T2-ADD-05 | hasRequiredAddons false khi chỉ có nhóm tuỳ chọn | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 13 |
| T2-ADD-06 | svcNameHTML gắn dấu sao cho dịch vụ bắt buộc add-on | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 15 |
| T2-ADD-07 | svcNameHTML không gắn dấu sao cho dịch vụ thường | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 23 |
| T2-ADD-08 | groupCount bằng 0 khi bản nháp còn rỗng | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 21 |
| T2-ADD-09 | groupCount đếm đúng số mục đã chọn trong cùng nhóm | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 27 |
| T2-ADD-10 | unmetRequired trả về đúng nhóm bắt buộc khi nháp rỗng | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 22 |
| T2-ADD-11 | unmetRequired rỗng khi đã chọn đủ min | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 22 |
| T2-ADD-12 | chọn vượt min vẫn hợp lệ, không coi là lỗi | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 28 |
| T2-ADD-13 | TẦNG MODAL: saveAddons không ghi vào giỏ khi còn nhóm thiếu | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 31 |
| T2-ADD-14 | TẦNG MODAL: saveAddons ghi addonIds khi đã đủ | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 26 |
| T2-ADD-15 | itemUnmetRequired chỉ ra nhóm còn thiếu của một mục trong giỏ | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 15 |
| T2-ADD-16 | TẦNG ĐƠN ĐẶT: tryLeaveStep2 không sang bước 3 khi còn dịch vụ thiếu | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 20 |
| T2-ADD-17 | TẦNG ĐƠN ĐẶT: tryLeaveStep2 sang bước 3 khi mọi dịch vụ đã đủ | Ràng buộc add-on | B4 B7 B8 B9 B10 | đạt | high | 22 |
| T2-AI18N-01 | hỗ trợ đủ 6 ngôn ngữ đã khai báo | App — đa ngôn ngữ | — | đạt | medium | 11 |
| T2-AI18N-02 | i18n trả đúng bản dịch của khoá có thật | App — đa ngôn ngữ | — | đạt | medium | 10 |
| T2-AI18N-03 | khoá không tồn tại trả về chính khoá đó, không phải undefined | App — đa ngôn ngữ | — | đạt | medium | 10 |
| T2-AI18N-04 | mọi khoá có đủ bản dịch cho cả 6 ngôn ngữ | App — đa ngôn ngữ | — | đạt | medium | 9 |
| T2-CAT-01 | filteredServices mặc định trả về danh sách không rỗng | Danh mục dịch vụ | B4 B5 | đạt | medium | 15 |
| T2-CAT-02 | chọn danh mục nào thì mọi kết quả thuộc danh mục đó | Danh mục dịch vụ | B4 B5 | đạt | medium | 32 |
| T2-CAT-03 | tìm kiếm "gel" chỉ trả về dịch vụ có chữ gel trong tên | Danh mục dịch vụ | B4 B5 | đạt | medium | 18 |
| T2-CAT-04 | tìm kiếm không phân biệt hoa thường và bỏ khoảng trắng thừa | Danh mục dịch vụ | B4 B5 | đạt | medium | 19 |
| T2-CAT-05 | từ khoá không khớp gì trả về danh sách rỗng | Danh mục dịch vụ | B4 B5 | đạt | medium | 15 |
| T2-CAT-06 | có từ khoá thì tìm kiếm ĐÈ danh mục, không giao nhau | Danh mục dịch vụ | B4 B5 | đạt | medium | 17 |
| T2-CAT-07 | xoá từ khoá thì danh sách quay về theo danh mục đang chọn | Danh mục dịch vụ | B4 B5 | đạt | medium | 24 |
| T2-CAT-08 | isSelected trả false khi giỏ rỗng | Danh mục dịch vụ | B4 B5 | đạt | medium | 14 |
| T2-CAT-09 | phoneAllServices là PREDICATE mobile, không phải danh sách dịch vụ | Danh mục dịch vụ | B4 B5 | đạt | medium | 75 |
| T2-HTML-01 | esc escape ký tự nguy hiểm của TEXT THÔ | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 4 |
| T2-HTML-02 | tên dịch vụ có & ra & đúng một lần | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 3 |
| T2-HTML-03 | memberBannerHTML khi CHƯA đăng nhập là dải mời, không có member-chip | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 3 |
| T2-HTML-04 | memberBannerHTML khi ĐÃ đăng nhập có chip, tên, hạng và điểm | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 17 |
| T2-HTML-05 | memberPhoneView có ô số điện thoại và hai lối tắt demo | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 4 |
| T2-HTML-06 | memberOtpView có đúng 4 ô nhập mã | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 4 |
| T2-HTML-07 | memberCardView hiện tên, hạng, điểm và danh sách quyền lợi | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 17 |
| T2-HTML-08 | addonItemHTML nêu cả giá và thời lượng của add-on | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 21 |
| T2-HTML-09 | timeSelectInner nhắc đúng thông điệp khi ngày không còn slot | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 4 |
| T2-HTML-10 | svcNameHTML: dấu sao chỉ có ở dịch vụ bắt buộc add-on | Dựng chuỗi | B3 B4 B9 C1 C2 C4 C6 B14 | đạt | low | 4 |
| T2-MEM-01 | memberSendCode chuyển sang màn nhập mã khi SĐT hợp lệ | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 14 |
| T2-MEM-02 | memberSendCode ở lại màn SĐT khi số sai định dạng | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 10 |
| T2-MEM-03 | mã chưa đủ 4 chữ số thì báo lỗi và không sang view thẻ | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 13 |
| T2-MEM-04 | KNOWN-ISSUE: mã sai vẫn đăng nhập được — chỉ kiểm độ dài memberVerify() chỉ kiểm độ dài mã, không so khớp giá trị — bản thật phải xác thực ở server |
Thành viên | C1 C2 C3 C4 C6 | lỗi đã biết | high | 14 |
| T2-MEM-05 | SĐT có trong danh bạ thì nạp đúng tên, điểm và hạng | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 18 |
| T2-MEM-06 | SĐT lạ tạo tài khoản mới với điểm chào mừng | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 16 |
| T2-MEM-07 | memberApply điền vào ô đang trống | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 18 |
| T2-MEM-08 | memberApply KHÔNG ghi đè thông tin khách đã tự nhập | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 21 |
| T2-MEM-09 | memberDemoFill chỉ điền số, chưa đăng nhập | Thành viên | C1 C2 C3 C4 C6 | đạt | high | 10 |
| T2-MONEY-01 | giỏ rỗng thì tổng bằng 0 | Tiền | B9 B11 | đạt | high | 15 |
| T2-MONEY-02 | một dịch vụ thì tổng đúng bằng giá dịch vụ đó | Tiền | B9 B11 | đạt | high | 17 |
| T2-MONEY-03 | hai dịch vụ thì tổng bằng tổng hai giá | Tiền | B9 B11 | đạt | high | 21 |
| T2-MONEY-04 | add-on cộng vào tổng | Tiền | B9 B11 | đạt | high | 25 |
| T2-MONEY-05 | cùng một add-on gắn cho hai dịch vụ thì tính HAI lần | Tiền | B9 B11 | đạt | high | 54 |
| T2-MONEY-06 | itemAddonPrice trả 0 cho add-on giá tuỳ chỉnh | Tiền | B9 B11 | đạt | high | 13 |
| T2-MONEY-07 | totalAddons đếm đúng tổng số add-on trong giỏ | Tiền | B9 B11 | đạt | high | 27 |
| T2-MONEY-08 | thêm rồi bỏ dịch vụ thì tổng quay về giá trị cũ | Tiền | B9 B11 | đạt | high | 27 |
| T2-MONEY-09 | reviewTotalHTML chứa đúng con số của bookingTotal | Tiền | B9 B11 | đạt | high | 20 |
| T2-MONEY-10 | totalValueLabel giữ đúng hai chữ số thập phân | Tiền | B9 B11 | đạt | high | 14 |
| T2-MONEY-11 | cộng nhiều add-on giá lẻ không sai số dấu phẩy động | Tiền | B9 B11 | đạt | high | 33 |
| T2-MONEY-12 | hasCustomItems và totalValueLabel khớp nhau khi giỏ toàn mục tuỳ chỉnh | Tiền | B9 B11 | đạt | high | 16 |
| T2-PBOOK-01 | bkKey ổn định cho cùng một booking | Portal — lịch hẹn | D2 | đạt | medium | 0 |
| T2-PBOOK-02 | bkKey khác nhau giữa hai booking khác nhau | Portal — lịch hẹn | D2 | đạt | medium | 1 |
| T2-PBOOK-03 | parseDate ghép đúng ngày tháng năm | Portal — lịch hẹn | D2 | đạt | medium | 0 |
| T2-PBOOK-04 | parseDate với đầu vào rỗng dùng giá trị mặc định, không ném | Portal — lịch hẹn | D2 | đạt | medium | 0 |
| T2-PBOOK-05 | itemsSummary đếm dịch vụ và add-on, không liệt kê tên | Portal — lịch hẹn | D2 | đạt | medium | 1 |
| T2-PBOOK-06 | fmtStaff hiển thị khác nhau giữa một và nhiều kỹ thuật viên | Portal — lịch hẹn | D2 | đạt | medium | 0 |
| T2-PBOOK-07 | staffCountLabel đổi nhãn theo số lượng | Portal — lịch hẹn | D2 | đạt | medium | 0 |
| T2-PBOOK-08 | cancelBooking đổi trạng thái lịch hẹn sắp tới | Portal — lịch hẹn | D2 | đạt | medium | 2 |
| T2-PBOOK-09 | SEED_BOOKINGS có đủ 6 lịch hẹn mẫu | Portal — lịch hẹn | D2 | đạt | medium | 1 |
| T2-PBOOK-10 | renderBookings dựng danh sách không rỗng | Portal — lịch hẹn | D2 | đạt | medium | 3 |
| T2-PMEM-01 | seedMember trả tài khoản mẫu đủ trường | Portal — tài khoản | D1 | đạt | medium | 0 |
| T2-PMEM-02 | freshMember tạo tài khoản mới không mang điểm của người khác | Portal — tài khoản | D1 | đạt | medium | 1 |
| T2-PMEM-03 | memberKey lấy theo số điện thoại, không phải tên | Portal — tài khoản | D1 | đạt | medium | 0 |
| T2-PMEM-04 | syncPoints suy điểm hiển thị = đã tích trừ đã tiêu, không âm | Portal — tài khoản | D1 | đạt | medium | 0 |
| T2-PNAV-01 | go() đổi được sang cả 7 khung nhìn | Portal — điều hướng | D1 | đạt | low | 6 |
| T2-PNAV-02 | go() chỉ nhận 7 view cố định — view lạ ném lỗi, không có đường thật chạm tới | Portal — điều hướng | D1 | đạt | low | 2 |
| T2-PNAV-03 | mỗi lần chỉ đúng MỘT mục điều hướng được đánh dấu | Portal — điều hướng | D1 | đạt | low | 5 |
| T2-PNAV-04 | mainTitle đổi theo danh sách dịch vụ được truyền vào | Portal — điều hướng | D1 | đạt | low | 0 |
| T2-PREV-01 | renderReviews tách nhóm chờ và nhóm đã gửi | Portal — đánh giá | D8 | đạt | low | 5 |
| T2-PREV-02 | huy hiệu điều hướng phản ánh số lịch hẹn chờ đánh giá | Portal — đánh giá | D8 | đạt | low | 1 |
| T2-PREV-03 | submitReview không ném với chỉ số hợp lệ | Portal — đánh giá | D8 | đạt | low | 5 |
| T2-PREV-04 | SEED_REVIEWS có 2 đánh giá mẫu | Portal — đánh giá | D8 | đạt | low | 1 |
| T2-PRWD-01 | rewardCardHTML dựng thẻ có tên, giá điểm và ảnh | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 2 |
| T2-PRWD-02 | thẻ phần thưởng vượt quá số điểm hiện có bị đánh dấu khoá | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 1 |
| T2-PRWD-03 | ảnh phần thưởng đều trỏ vào assets/reward-* | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 0 |
| T2-PRWD-04 | REDEEM_CATALOG đúng 6 mục với bộ giá điểm đã biết | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 0 |
| T2-PRWD-05 | askRedeem mở modal và nêu đúng chi phí, số dư sau khi đổi | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 1 |
| T2-PRWD-06 | confirmRedeem trừ đúng điểm và sinh voucher mới | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 20 |
| T2-PRWD-07 | không đủ điểm thì askRedeem KHÔNG mở modal và không trừ điểm | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 1 |
| T2-PRWD-08 | openCashRedeem mở bảng mức đổi tiền | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 3 |
| T2-PRWD-09 | selectCashTier tính trước số dư còn lại sau khi đổi | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 2 |
| T2-PRWD-10 | confirmCashRedeem trừ điểm và thêm voucher | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 22 |
| T2-PRWD-11 | lockedPerkCardHTML nêu tên quyền lợi và hạng cần đạt | Portal — đổi thưởng | D5 D6 D7 | đạt | high | 2 |
| T2-PSOC-01 | toggleSocial bật rồi tắt một mục | Portal — mạng xã hội | D9 | đạt | low | 33 |
| T2-PSOC-02 | resetSocials đưa về trạng thái mặc định | Portal — mạng xã hội | D9 | đạt | low | 1 |
| T2-PTHEME-01 | setTheme("light") gắn class light lên body | Portal — theme | D11 | đạt | low | 1 |
| T2-PTHEME-02 | setTheme("dark") gỡ class light | Portal — theme | D11 | đạt | low | 1 |
| T2-PTHEME-03 | setTheme ghi lựa chọn vào localStorage | Portal — theme | D11 | đạt | low | 1 |
| T2-PTHEME-04 | mặc định là SÁNG khi chưa có sonaTheme | Portal — theme | D11 | đạt | low | 1 |
| T2-PVCH-01 | genCode đúng định dạng SONA-XXXXXX | Portal — voucher | D3 D4 | đạt | medium | 1 |
| T2-PVCH-02 | genCode không trùng qua nhiều lần gọi | Portal — voucher | D3 D4 | đạt | medium | 1 |
| T2-PVCH-03 | copyCode ghi đúng mã vào clipboard | Portal — voucher | D3 D4 | đạt | medium | 1 |
| T2-PVCH-04 | openQR lấy đúng voucher theo chỉ số | Portal — voucher | D3 D4 | đạt | medium | 1 |
| T2-PVCH-05 | openQR với chỉ số ngoài dải không mở QR im lặng sai | Portal — voucher | D3 D4 | đạt | medium | 2 |
| T2-PVCH-06 | VOUCHERS và GIFTED_VOUCHERS có mã không trùng nhau | Portal — voucher | D3 D4 | đạt | medium | 1 |
| T2-SEL-01 | thêm một dịch vụ thì isSelected true và giỏ tăng 1 | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 18 |
| T2-SEL-02 | gọi lại chính dịch vụ đó thì bỏ khỏi giỏ | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 19 |
| T2-SEL-03 | thêm ba dịch vụ khác nhau thì cả ba đều nằm trong giỏ | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 26 |
| T2-SEL-04 | bỏ dịch vụ đang có add-on thì add-on biến mất theo, không thành mồ côi | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 26 |
| T2-SEL-05 | toggleService với id lạ ném lỗi — ghi nhận, chưa có đường thật chạm tới | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 17 |
| T2-SEL-06 | isSelected false với mọi dịch vụ khi giỏ rỗng | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 13 |
| T2-SEL-07 | hasCustomItems phân biệt giỏ chuẩn với giỏ có mục tuỳ chỉnh giá | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 20 |
| T2-SEL-08 | totalAddons đếm add-on trên toàn giỏ, không phải theo từng dịch vụ | Giỏ dịch vụ | B6 B11 B13 | đạt | medium | 24 |
| T2-SESS-01 | saveSession ghi khoá sonaSession dưới dạng JSON đọc được | Phiên & hash | B14 C6 E1 E2 | đạt | high | 21 |
| T2-SESS-02 | hydrateSession khôi phục danh tính thành viên đã lưu | Phiên & hash | B14 C6 E1 E2 | đạt | high | 24 |
| T2-SESS-03 | hydrateSession không ném khi JSON hỏng | Phiên & hash | B14 C6 E1 E2 | đạt | high | 5 |
| T2-SESS-04 | hydrateSession không ghi đè phiên đang đăng nhập | Phiên & hash | B14 C6 E1 E2 | đạt | high | 17 |
| T2-SESS-05 | persistMember ghi đúng số điểm của tài khoản | Phiên & hash | B14 C6 E1 E2 | đạt | high | 17 |
| T2-SESS-06 | điểm đã tích không bị ghi đè — lấy giá trị LỚN HƠN | Phiên & hash | B14 C6 E1 E2 | đạt | high | 24 |
| T2-SESS-07 | memberSignOut hạ cờ isMember nhưng không xoá cả phiên | Phiên & hash | B14 C6 E1 E2 | đạt | high | 22 |
| T2-SESS-08 | pauseMemberDraft giữ giỏ nhưng buộc chọn lại ngày giờ | Phiên & hash | B14 C6 E1 E2 | đạt | high | 32 |
| T2-SESS-09 | resetWizardState dọn sạch giỏ | Phiên & hash | B14 C6 E1 E2 | đạt | high | 18 |
| T2-SESS-10 | portalHref mang cả sonaSession qua hash dạng #s= | Phiên & hash | B14 C6 E1 E2 | đạt | high | 18 |
| T2-SESS-11 | nạp với hash #book-dark|m={…}: bật theme nhúng và tự điền, không ghi đè | Phiên & hash | B14 C6 E1 E2 | đạt | high | 80 |
| T2-TIER-01 | bảng TIERS 4 hạng, mốc tăng dần 0/400/1000/2500 | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-02 | 0 và 399 điểm còn ở Bronze — nhắm tới Silver | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-03 | biên dưới Silver: 400 điểm đã sang Silver, nhắm tới Gold | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-04 | biên dưới Gold: 1000 điểm nhắm tới VIP | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-05 | 2500 điểm trở lên là hạng cao nhất, không còn hạng sau | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-06 | điểm âm không làm vỡ và không rơi ra ngoài dải | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-07 | 820 điểm còn đúng 180 điểm nữa lên Gold | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-08 | phần trăm tiến trình nằm trong 0..100 ở mọi mốc | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-09 | tierIcon có 3 biểu tượng cho 4 hạng — Bronze và Silver dùng chung | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIER-10 | memberRewardBlock nêu đúng số điểm kiếm được của đơn | Hạng thẻ | B14 C4 C5 | đạt | medium | 0 |
| T2-TIME-01 | todayISO theo đồng hồ đã đóng băng | Ngày giờ | B1 B3 | đạt | high | 39 |
| T2-TIME-02 | nowMinutes tại 09:00 là 540 | Ngày giờ | B1 B3 | đạt | high | 31 |
| T2-TIME-03 | nowMinutes tại hai biên nửa đêm | Ngày giờ | B1 B3 | đạt | high | 90 |
| T2-TIME-04 | slotMinutes xử lý đúng bẫy 12 giờ | Ngày giờ | B1 B3 | đạt | high | 31 |
| T2-TIME-05 | ngày tương lai có đủ 31 slot | Ngày giờ | B1 B3 | đạt | high | 33 |
| T2-TIME-06 | ngày quá khứ không còn slot nào | Ngày giờ | B1 B3 | đạt | high | 31 |
| T2-TIME-07 | hôm nay lúc 09:00 cắt còn 26 slot, bắt đầu từ 9:30 AM | Ngày giờ | B1 B3 | đạt | high | 34 |
| T2-TIME-08 | trước giờ mở cửa thì hôm nay vẫn đủ 31 slot | Ngày giờ | B1 B3 | đạt | high | 41 |
| T2-TIME-09 | sau giờ đóng cửa thì hôm nay hết slot | Ngày giờ | B1 B3 | đạt | high | 30 |
| T2-TIME-10 | mốc cắt là now+30 phút, không lệch một slot | Ngày giờ | B1 B3 | đạt | high | 65 |
| T2-TIME-11 | slotOptionsHTML dựng đủ 31 option cho ngày tương lai | Ngày giờ | B1 B3 | đạt | high | 32 |
| T2-TIME-12 | slot đã có người đặt vẫn hiện nhưng bị disabled kèm nhãn | Ngày giờ | B1 B3 | đạt | high | 38 |
| T2-TIME-13 | slotOptionsHTML đánh dấu đúng một option được chọn | Ngày giờ | B1 B3 | đạt | high | 31 |
| T2-TIME-14 | noSlotMsg khi chưa chọn ngày | Ngày giờ | B1 B3 | đạt | high | 28 |
| T2-TIME-15 | noSlotMsg cho ngày đã qua | Ngày giờ | B1 B3 | đạt | high | 31 |
| T2-TIME-16 | noSlotMsg khi hôm nay đã hết giờ | Ngày giờ | B1 B3 | đạt | high | 29 |
| T2-TIME-17 | addDaysISO cộng đúng qua cuối tháng, cuối năm và năm nhuận | Ngày giờ | B1 B3 | đạt | high | 37 |
| T2-TIME-18 | firstBookableDate nhảy sang hôm sau khi hôm nay đã hết slot | Ngày giờ | B1 B3 | đạt | high | 57 |
| T2-VAL-01 | phoneValid nhận số hợp lệ có khoảng trắng | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-02 | phoneValid biên dưới: đúng 7 chữ số là hợp lệ | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-03 | phoneValid biên dưới: 6 chữ số bị loại | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-04 | phoneValid biên trên: đúng 15 chữ số là hợp lệ | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-05 | phoneValid biên trên: 16 chữ số bị loại | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-06 | phoneValid loại chuỗi có chữ cái | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-07 | phoneValid loại chuỗi rỗng và toàn khoảng trắng | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-08 | phoneValid chấp nhận ký tự phân cách thường gặp | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-09 | emailValid coi rỗng là hợp lệ vì email tuỳ chọn | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-10 | emailValid trim trước khi xét | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-11 | emailValid nhận địa chỉ đúng dạng | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-12 | emailValid loại ba dạng sai | Hợp lệ hoá | B1 B2 | đạt | high | 0 |
| T2-VAL-13 | step1Valid true khi đủ tên, SĐT, ngày và giờ | Hợp lệ hoá | B1 B2 | đạt | high | 9 |
| T2-VAL-14 | step1Valid false khi thiếu bất kỳ trường bắt buộc nào | Hợp lệ hoá | B1 B2 | đạt | high | 23 |
| T3-BOOK-01 | ba nút Book Appointment cùng mở một wizard | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 49 |
| T3-BOOK-02 | bước 1 hiện đủ các trường bắt buộc | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 10 |
| T3-BOOK-03 | bấm Next khi form trống thì ở lại bước 1 và đánh dấu ô thiếu | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 12 |
| T3-BOOK-04 | điền đủ rồi Next thì sang bước chọn dịch vụ | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 25 |
| T3-BOOK-05 | nút tăng giảm số khách dừng đúng ở biên 1 và 12 | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 14 |
| T3-BOOK-06 | đổi ngày làm danh sách giờ vẽ lại | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 26 |
| T3-BOOK-07 | bấm danh mục thì danh sách dịch vụ đổi | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 27 |
| T3-BOOK-08 | gõ tìm kiếm thu hẹp danh sách, xoá thì phục hồi | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 30 |
| T3-BOOK-09 | thêm dịch vụ thì nút đổi thành Remove và giỏ có hàng | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 27 |
| T3-BOOK-10 | nút Next của bước 2 bị khoá khi giỏ rỗng | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 25 |
| T3-BOOK-11 | mở Bundled add-ons thì modal hiện nhóm kèm nhãn Required | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 37 |
| T3-BOOK-12 | Save khi thiếu add-on bắt buộc thì modal KHÔNG đóng | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 33 |
| T3-BOOK-13 | chọn add-on rồi Save thì modal đóng và giỏ ghi nhận | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 33 |
| T3-BOOK-14 | Next ở bước 2 khi chưa mở add-on bắt buộc hiện dải cảnh báo nêu tên dịch vụ | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 28 |
| T3-BOOK-15 | ở bước xem lại, xoá một dòng thì tổng tiền đổi | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 41 |
| T3-BOOK-16 | ghi chú tiếng Việt có dấu giữ nguyên trong DOM | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 34 |
| T3-BOOK-17 | hộp thoại xoá nêu đúng tên; Cancel giữ nguyên, Xác nhận mới xoá | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 29 |
| T3-BOOK-18 | xác nhận đặt lịch hiện màn thành công kèm gợi ý điểm | Luồng đặt lịch | A1 B1 B2 B3 B4 B5 B6 B7 B8 B9 B10 B11 B12 B13 B14 | đạt | high | 33 |
| T3-INT-01 | bấm New Booking mở lớp phủ và nạp iframe, không rời trang | Tích hợp hai file | E1 E2 | đạt | high | 109 |
| T3-INT-02 | địa chỉ iframe đúng dạng booking-popup.html#<theme>|m=<JSON> | Tích hợp hai file | E1 E2 | đạt | high | 67 |
| T3-INT-03 | popup nạp bằng hash đó thì vào chế độ nhúng, tối, đã đăng nhập | Tích hợp hai file | E1 E2 | đạt | high | 115 |
| T3-INT-04 | portal ở theme sáng thì popup nhận #book, không phải #book-dark | Tích hợp hai file | E1 E2 | đạt | high | 107 |
| T3-INT-05 | popup nhúng KHÔNG điều hướng khi bấm xem portal — chỉ đóng modal | Tích hợp hai file | E1 E2 | đạt | high | 145 |
| T3-MEM-01 | mở Sona Rewards từ dải mời trong bước 1 | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 34 |
| T3-MEM-02 | số điện thoại đã nhập ở bước 1 được mượn sang modal | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 22 |
| T3-MEM-03 | lối tắt demo chỉ điền số, chưa gửi mã và chưa đăng nhập | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 19 |
| T3-MEM-04 | gõ đủ 4 chữ số thì nút xác nhận mở khoá | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 28 |
| T3-MEM-05 | xác nhận khi thiếu chữ số thì hiện đúng dòng lỗi | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 18 |
| T3-MEM-06 | đăng nhập hai hạng khác nhau hiện đúng thẻ tương ứng | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 45 |
| T3-MEM-07 | bấm OK trên thẻ thì bước 1 đổi sang chip và tự điền | Luồng thành viên | C1 C2 C3 C4 C5 C6 | đạt | high | 32 |
| T3-PORT-01 | portal nhận đúng thành viên và chào theo tên | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 3 |
| T3-PORT-02 | bấm lần lượt 7 mục điều hướng thì đúng một khung nhìn bật | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 17 |
| T3-PORT-03 | lịch sử đặt lịch có dữ liệu và hiện trạng thái | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 5 |
| T3-PORT-04 | bấm sao chép mã ghi đúng giá trị (clipboard là stub — NC-02) | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 3 |
| T3-PORT-05 | mở QR hiện overlay với mã chữ đi kèm (pixel canvas là NC-01) | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 8 |
| T3-PORT-06 | danh mục đổi thưởng hiện đủ 6 phần thưởng | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 12 |
| T3-PORT-07 | đổi thưởng đủ điểm: modal nêu chi phí rồi trừ đúng | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 40 |
| T3-PORT-08 | đổi thưởng thiếu điểm bị chặn, không mở modal | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 16 |
| T3-PORT-09 | bảng đổi điểm lấy tiền mở được và có các mức | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 7 |
| T3-PORT-10 | khung đánh giá tách nhóm chờ và đã gửi | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 4 |
| T3-PORT-11 | sửa hồ sơ rồi đổi khung nhìn thì dữ liệu không mất | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 4 |
| T3-PORT-12 | khung nhìn Testing mở được, không lỗi handler | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 2 |
| T3-PORT-13 | đổi theme và ghi nhớ theo thiết bị | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 4 |
| T3-PORT-14 | đăng xuất hỏi lại trước khi thực hiện | Luồng portal | D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 | đạt | medium | 3 |
| T4-01 | 1440px: stepper 3 bước | Responsive | B15 B16 D12 D13 | đạt | medium | 75 |
| T4-02 | 390px: stepper 4 bước, có mốc Add-ons | Responsive | B15 B16 D12 D13 | đạt | medium | 76 |
| T4-03 | biên của stepper là SPLIT_MQ 880/881px, KHÔNG phải 480px | Responsive | B15 B16 D12 D13 | đạt | medium | 118 |
| T4-04 | biên PHONE_MQ 480/481px chi phối phoneAllServices | Responsive | B15 B16 D12 D13 | đạt | medium | 65 |
| T4-05 | hẹp thì danh sách và giỏ tách hai trang; rộng thì hiện cùng lúc | Responsive | B15 B16 D12 D13 | đạt | medium | 123 |
| T4-06 | đổi 1440 → 390 giữa chừng: wizard vẽ lại, dữ liệu đang nhập không mất | Responsive | B15 B16 D12 D13 | đạt | medium | 42 |
| T4-07 | portal 390px: ngăn kéo mở/đóng bằng class open | Responsive | B15 B16 D12 D13 | đạt | medium | 51 |
| T4-08 | app-booking cùng hành vi stepper như web-booking | Responsive | B15 B16 D12 D13 | đạt | medium | 328 |
Sinh bởi report/build.mjs · ledger 252 case · nguồn kết quả: junit.xml