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