QA Bug Playground

UI Bugs Playground

🇻🇳 Sân chơi lỗi giao diện

1. Disabled button

🇻🇳 Nút bị vô hiệu hóa (giả)

This "Place Order" button is supposed to be disabled until you agree to terms.

💡 Hint: The button only has opacity:.5 for the greyed-out look — it's missing the disabled attribute, so it's still fully clickable even without checking the box.
🇻🇳 Nút chỉ được làm mờ bằng opacity:.5 cho có vẻ bị vô hiệu hóa — nó thiếu thuộc tính disabled thật sự, nên vẫn bấm được dù chưa tick điều khoản.

2. Modal dialog

🇻🇳 Hộp thoại modal
💡 Hint: The close (X) button's click handler looks up an element ID that doesn't exist (a leftover from a rename), so its own click does nothing. Reload the page to escape.
🇻🇳 Nút đóng (X) tra cứu một ID phần tử không tồn tại (sót lại từ lúc đổi tên), nên click vào nó chẳng có tác dụng gì. Phải tải lại trang mới thoát được.

3. Dropdown menu

🇻🇳 Menu thả xuống
💡 Hint: The card wraps its content with overflow:hidden, so the dropdown gets visually clipped at the card's edge instead of floating above it.
🇻🇳 Thẻ card bọc nội dung bằng overflow:hidden, nên menu thả xuống bị cắt cụt ở mép thẻ thay vì nổi lên trên.

4. Tabs

🇻🇳 Tab điều hướng
Tab 1 content
💡 Hint: Every tab's click handler is hardcoded to index 0 instead of reading its own data-tab value, so Tab 2 and Tab 3 always render Tab 1's content.
🇻🇳 Handler click của mọi tab đều bị gán cứng index 0 thay vì đọc giá trị data-tab của chính nó, nên Tab 2 và Tab 3 luôn hiển thị nội dung của Tab 1.

5. Star rating

🇻🇳 Đánh giá sao
☆☆☆☆☆

Click a star to rate.

💡 Hint: The click handler adds +1 to the computed star index on top of the rounding it already does, so whatever star you click, the displayed rating is always one higher than expected.
🇻🇳 Handler click cộng thêm +1 vào chỉ số sao đã tính, nên dù bấm vào sao nào thì số sao hiển thị luôn cao hơn 1 so với mong đợi.

6. Counter

🇻🇳 Bộ đếm
0
💡 Hint: The two click handlers are wired to the wrong buttons: "+1" subtracts and "-1" adds. Easy to miss if you only glance at the label instead of watching the number change.
🇻🇳 Hai handler click bị gắn nhầm nút: "+1" thì trừ, "-1" thì cộng. Rất dễ bỏ sót nếu chỉ liếc nhãn nút mà không theo dõi số thay đổi.

7. Accordion

🇻🇳 Accordion (thu gọn/mở rộng)

This panel contains a longer paragraph of details that should be fully readable once expanded, covering shipping times, return policy, and warranty information for the product in question.

💡 Hint: The expanded state animates to a fixed max-height:40px, which is shorter than the actual paragraph, so the bottom of the text stays clipped no matter how long you wait.
🇻🇳 Trạng thái mở rộng chỉ animate tới max-height:40px cố định, ngắn hơn đoạn văn thật, nên phần cuối văn bản luôn bị cắt dù chờ bao lâu.

8. Broken image

🇻🇳 Ảnh bị vỡ
💡 Hint: The image src points at a file that was never deployed, and there's no alt text either — so sighted users see a broken-image icon and screen-reader users get nothing at all.
🇻🇳 Đường dẫn ảnh trỏ tới file chưa từng được deploy, và cũng không có alt text — người dùng nhìn thấy icon ảnh vỡ, còn người dùng screen reader thì chẳng nhận được gì cả.

9. Password visibility toggle

🇻🇳 Nút hiện/ẩn mật khẩu
💡 Hint: The button swaps its own icon/label text between "Show" and "Hide", but the code never actually flips the input's type between password and text — so the value stays masked forever.
🇻🇳 Nút chỉ đổi icon/nhãn giữa "Show" và "Hide", nhưng code không hề đổi type của input giữa password và text — nên giá trị luôn bị ẩn mãi mãi.

10. Toast notification

🇻🇳 Thông báo toast
💡 Hint: The toast auto-dismisses after only 250ms (far too fast to read) and its z-index is lower than the header's, so it can render underneath the nav bar depending on scroll position.
🇻🇳 Toast tự biến mất chỉ sau 250ms (quá nhanh để đọc) và z-index thấp hơn header, nên có thể bị nằm dưới thanh nav tùy vị trí cuộn trang.

11. Long text overflow

🇻🇳 Tràn văn bản dài

Order reference:

ORD-8842991029384756abcdef0123456789fedcba9876543210deadbeefcafefeedfacebeef1234567890

💡 Hint: This string has no word-break/overflow-wrap styling, so on narrow screens it forces the whole page to scroll horizontally instead of wrapping.
🇻🇳 Chuỗi này không có style word-break/overflow-wrap, nên trên màn hình hẹp nó buộc cả trang phải cuộn ngang thay vì tự xuống dòng.

12. Pagination

🇻🇳 Phân trang
Page 1 of 3
💡 Hint: The Next button never checks against the last page, so clicking it past page 3 keeps counting up forever ("Page 7 of 3") instead of disabling itself or clamping.
🇻🇳 Nút Next không bao giờ kiểm tra so với trang cuối, nên bấm quá trang 3 thì số trang cứ tăng mãi ("Page 7 of 3") thay vì tự vô hiệu hóa hoặc giới hạn lại.

13. Submit button (double-click)

🇻🇳 Nút submit (bấm đúp)

Submitted count: 0

💡 Hint: The button is never disabled or debounced after the first click, so a fast double-click (or a slow network) submits the form twice — in a real checkout this means two orders or two charges.
🇻🇳 Nút không hề bị vô hiệu hóa hay debounce sau lần click đầu tiên, nên bấm đúp nhanh (hoặc mạng chậm) sẽ submit form hai lần — trong một checkout thật, điều này nghĩa là hai đơn hàng hoặc bị tính tiền hai lần.

14. Keyboard tab order

🇻🇳 Thứ tự Tab bàn phím
💡 Hint: Click into this row then press Tab repeatedly. Explicit (and inconsistent) tabindex values make keyboard focus jump Second → Third → First instead of following the visual left-to-right order — a real problem for keyboard-only and screen-reader users, and one that's invisible if you only click with a mouse.
🇻🇳 Click vào hàng này rồi bấm Tab liên tục. Giá trị tabindex tường minh (và không nhất quán) khiến focus bàn phím nhảy Second → Third → First thay vì theo đúng thứ tự trái-phải trên màn hình — vấn đề thật sự với người dùng chỉ dùng bàn phím hoặc screen reader, và hoàn toàn vô hình nếu bạn chỉ dùng chuột.

15. Sortable table

🇻🇳 Bảng có thể sắp xếp
ItemPrice ▾
Mouse19.99
Keyboard89.50
USB Hub34.00
💡 Hint: Clicking the "Price" header flips the sort arrow and logs a sorted array in code, but the sorted result is never written back into the table's DOM — so the row order on screen never actually changes.
🇻🇳 Bấm vào tiêu đề "Price" chỉ đổi hướng mũi tên và tạo ra một mảng đã sắp xếp trong code, nhưng kết quả đó không bao giờ được ghi lại vào DOM của bảng — nên thứ tự dòng trên màn hình không hề thay đổi.

16. Autofocus placement

🇻🇳 Vị trí autofocus
💡 Hint: This input has the autofocus attribute even though it's halfway down the page, so on load the browser silently scrolls/jumps you to it instead of leaving you at the top of the page.
🇻🇳 Ô nhập này có thuộc tính autofocus dù nó nằm giữa trang, nên khi tải trang, trình duyệt sẽ tự động cuộn/nhảy tới đó thay vì để bạn ở đầu trang.

17. Load more (infinite scroll)

🇻🇳 Tải thêm (infinite scroll)
💡 Hint: The button always appends the same hardcoded Item 1/2/3 instead of tracking an offset/cursor, so clicking it repeatedly just duplicates the same three items instead of loading new ones.
🇻🇳 Nút luôn thêm vào đúng 3 item Item 1/2/3 được gán cứng thay vì theo dõi offset/cursor, nên bấm nhiều lần chỉ tạo ra các bản sao trùng lặp thay vì tải dữ liệu mới.