QA Bash Learning
Element Playground.
40+ live elements to practice locators on — each with a ranked strategy list. Test your own selector against the real page with the bar at the bottom.
Every card's ⓘ icon and copy button carry data-qb-chrome — exclude them with a selector like button:not([data-qb-chrome]) if you're testing something broad in the bar below.
Text Inputs
Standard Text Input
EasyPassword Input
EasyEmail Input — ARIA Label Only
MediumNo id, name, or data-testid on this one — ARIA is the only strong option. This is intentional: plenty of real forms look exactly like this.
Disabled Number Input
EasyDisabled elements are still locatable — most frameworks require an explicit enabled-state check before you can interact with them.
Readonly Search Input
MediumZero-Attribute Textarea
HardNo id, name, aria-label, or test id at all. In a real app, flag this to a developer — but you still need to test it today, so placeholder is the least-bad option.
Selection Controls
Single Checkbox
EasyCheckbox Group
MediumRadio Group
EasyNative Select — Single
EasyNative Select — Multiple
MediumCustom JS Dropdown
HardThis isn't a native <select> — it won't respond to selectOption(). Click the trigger, then click the option in the opened listbox.
Toggle Switch
Easyaria-checked flips when toggled — don't hardcode the current state into your selector.
Range Slider
MediumDynamic & Timing Challenges
Appears After Delay
MediumWaiting… (appears at 3s)
Doesn't exist in the DOM for the first 3 seconds after this section mounts — use an explicit wait/assertion with a timeout, not an immediate query.
Countdown-Enabled Button
MediumExists immediately but stays disabled for 5 seconds — wait for the disabled attribute to clear, don't just wait for the element to exist.
Auto-Refreshing Counter
HardText content changes every 2 seconds — don't assert exact text, assert a pattern or that the value changed between two reads.
Regenerating-ID Element
Expertcurrent id: field-…
The classic dynamic-ID trap — common in frameworks like Angular Material or MUI that auto-generate IDs. Always check whether an ID looks suspicious (long random suffix) before trusting it.
Typeahead / Autocomplete
HardThe options list doesn't exist until you type — query it after triggering input, not before.
Infinite Scroll List
Hard- Result #1
- Result #2
- Result #3
- Result #4
- Result #5
- Result #6
New items only mount once you scroll near the bottom — for items beyond the initial batch, scroll the container into view first, then re-query.
Overlays
Modal Dialog
MediumFocus is trapped inside while open — Tab won't reach elements behind it. Close via Cancel/Confirm or Escape; there's no backdrop-click-to-close here.
Toast (Auto-Dismiss)
MediumAuto-dismisses after 3 seconds — assert on it immediately after triggering, don't add a long wait first or you'll query after it's gone.
Hover-Only Tooltip
MediumThe tooltip content is only in the DOM while the trigger is hovered or focused — hover() or focus() the trigger before asserting it's visible.
Right-Click Context Menu
HardTriggered by the contextmenu event, not a normal click — most frameworks need an explicit right-click/contextmenu action, not click().
Cookie Consent Banner
MediumDismissed.
State-dependent — once dismissed it stays hidden (stored in localStorage) until you hit Reset. Good practice for testing first-visit vs. returning-visitor scenarios.
Structural & Frames
Same-Origin Iframe
MediumYou must switch into the iframe's context before interacting with elements inside it (Playwright's frameLocator(), Selenium's driver.switchTo().frame()).
Nested Iframe
HardTwo frame switches deep — switch into the outer frame, then into the inner one, before the button becomes reachable.
Shadow DOM Component
ExpertReal shadow DOM (mode: open). Playwright's locator() pierces shadow roots automatically; plain document.querySelectorAll/XPath cannot — try the Selector Tester below on a selector for the button inside and watch it return 0 matches.
Sortable + Paginated Table
Hard| Name ↕ | Role |
|---|---|
| Carol White | QA Lead |
| Bob Smith | SDET |
| Alice Johnson | Automation Engineer |
Row order changes when sorted and the row set changes per page — don't hardcode 'row 3' as an identifier; locate by the cell's actual content instead.
HTML5 Drag and Drop
HardDrop here
Native HTML5 drag-and-drop doesn't respond to simple mouse-down/move/up sequences in most tools — use Playwright's dragTo() or Selenium's Actions dragAndDrop(), built specifically for this.
File Upload
MediumFile inputs can't be 'typed' into for security reasons — use setInputFiles() (Playwright) or sendKeys(path) (Selenium) directly on the <input type="file">, never simulate a click-then-type.
Advanced & Ambiguous
5 Identical Buttons
ExpertAll five buttons are byte-for-byte identical markup. If this were a real app, ask a developer for a unique attribute per row — until then, position is genuinely your only lever.
Zero-Attribute Element
HardNo id, class, or test id at all — just a bare <span>. In a real app, flag this to a developer; until then, text content is your only lever.
Decoy-Attribute Trap
ExpertEvery attribute on this button looks promising and is actually unreliable — a realistic example of why 'has an id' isn't the same as 'has a stable id'.
SVG Icon Button
MediumSibling-Context-Only Element
Expert| Widget A | |
| Widget B |
Classic 'find the button in the row that contains X' problem — most frameworks solve this with a scoped/filtered locator (e.g. Playwright's .filter({ has: ... })), not a single global CSS selector.
QA Bash's Element Playground is a free, live locator-practice page with 40+ interactive elements across 7 categories — text inputs, selection controls, buttons, dynamic/timing traps, overlays, iframes and shadow DOM, and deliberately ambiguous cases. Every element has a ranked locator list (best strategy to worst, with the real selector and why), and a live Selector Tester at the bottom evaluates any CSS selector or XPath you type against the real page, highlighting matches instantly.
Practice pages, but with a feedback loop.
Live Selector Tester
Type any CSS selector or XPath and see it evaluated against the real page — matches get a pulsing highlight and a live count. Nowhere else lets you test the guess in place.
Ranked locators per element
Every element's info icon opens a ranked list — best strategy to worst — with the exact selector, a verdict, and why, not just a generic tip.
40+ elements, 7 categories
From a plain text input to a real shadow DOM component, a five-identical-buttons trap, and an ID that regenerates on every reload.
Real overlays, not screenshots
A focus-trapped modal, an auto-dismissing toast, a hover-only tooltip, a right-click context menu, and a state-dependent cookie banner — all genuinely interactive.
Frames and shadow DOM done right
Same-origin and nested iframes via srcDoc, plus a real attachShadow(mode:'open') component — watch the Selector Tester return 0 matches inside it and see why.
Difficulty-tagged
Easy through Expert, so you can specifically drill the hard cases — dynamic IDs, decoy attributes, sibling-scoped locators — instead of only the easy ones.
Frequently asked questions.
Is this free, and do I need an account?
Yes to both — free, no signup required. Every element and the Selector Tester work without logging in.
What's the difference between this and selectorshub.com's practice page?
Every element here has a ranked, worked-example locator list (best strategy to worst, with the actual selector and why) built in, and the live Selector Tester lets you test your own guess against the real page and see it highlighted — most practice pages give you elements with no feedback loop at all.
Why does the shadow DOM element show 0 matches when I test a selector on it?
That's intentional and correct — standard CSS selectors and XPath genuinely cannot pierce an open shadow root from outside it. Playwright's locator() can; plain document.querySelectorAll() and XPath cannot. The 0-match result is the lesson.
Do the ranked locators actually match the live markup?
Yes — every selector shown in a Ranked Locators panel is copy-paste-able directly into the Selector Tester bar and will match the real element on the page.
Can I use this to demo locator strategies to my team?
Yes — it's a public page, so you can link directly to a category (e.g. #dynamic-timing) or a specific element card.
Is there a backend API practice page too?
Yes — see API Playground for a sample REST + GraphQL backend with CRUD, auth, and deliberate error cases (409 conflicts, 401 vs 403, flaky/slow/rate-limited endpoints).