🧱 HTML: The Raw Material of Locators
HTML: The Raw Material of Locators: HTML is the SKELETON and LABELING system of a building: a ` ` is a door, a ` ` a corridor, and `id`/`class`/`data-*` are the name tags hung on
HTML is the SKELETON and LABELING system of a building: a ` ` is a door, a ` ` a corridor, and `id`/`class`/`data-*` are the name tags hung on the doors. What you call a locator is really the question "which tag do I read to find the right door?" Why is one tag better than another? Because some tags (data-testid) are hung only for testers and never change; others (class) are hung for decoration and fall off when the paint changes (a new deploy). Java analogy: like choosing which field to use for an object's `equals/hashCode` — pick an unstable field and the relationship breaks. In QA context: a tester who can read HTML "with a locator's eye" can ask the developer for the right tag (a durable hook); one who cannot is condemned to blind XPath.
🚪 B1. Semantic Elements: header, nav, main, button, a
A semantic HTML element is like an official DOOR SIGN reading "THIS IS A BUTTON, PRESSABLE": ` ` carries this sign automatically, while a ` ` is just a painted door — the human eye thinks they are the same, but the firefighter (screen reader/accessibility API) only registers the one with the sign as a "door". So why should I use ` ` instead of ` ` when both are clickable and look the same? Java analogy: ` ` implements the browser's "Clickable" interface for free — automatic focus, keyboard support, and a role come built in; ` ` does not implement that interface, so you must rewrite every method (tabindex, role, keydown listener) BY HAND. In QA context: a page using ` ` both excludes screen-reader users and makes a durable locator strategy like `getByRole('button')` IMPOSSIBLE — when a tester sees this they ask the developer to switch to the semantic element.
🎬 Semantic Element or Div? The Accessibility Tree's Verdict
role="button" (automatic)
There are two "Save" buttons that look PIXEL-IDENTICAL: one is a real ` `, the other is just a ` ` styled to look like a button. To the eye there is no difference — but in this film you will see how the browser treats them DIFFERENTLY.
Step 1 — Both enter the DOM: the parser adds both as nodes in the tree. At this point there is still no difference; the DOM treats both equally.
Step 2 — The Accessibility Tree is built: the browser builds a second tree that extracts each element's "meaning" (role, name, state) — this is what the screen reader AND `getByRole` see.
Step 3 — ` ` AUTOMATICALLY gets an identity: role="button", name="Save" (derived from its text), focusable with Tab, triggerable with Enter/Space. No extra code was written — this is built into the element's nature.
Step 4 — ` ` gets NO identity at all: its role in the accessibility tree is "generic" (meaningless), it cannot be focused with Tab, it is not triggered by Enter/Space — it only works with a mouse click. A screen-reader user NEVER learns it is clickable.
Final — The locator outcome: `getByRole('button', { name: 'Save' })` finds ONLY the real ` `; it never finds ` ` because it has no role. What to ask the developer? "Use a real ` `; if a div is truly needed, add `role="button" tabindex="0"` and keyboard support." A semantic element wins accessibility AND the locator at the same time.
A developer says "` ` and ` ` do the same job: both are clickable". What is missing from this claim?
Nothing is missing, they are identical
A ` ` gets no role/name/keyboard support in the accessibility tree; `getByRole` cannot find it and a screen reader does not know it is clickable