| Pattern | Syntax | Example |
|---|---|---|
| ID | #id | #userId |
| Class | .class | .product-card |
| Tag | tag | input |
| Exact attr | [attr='val'] | [data-testid='loginBtn'] |
| Starts with | [attr^='val'] | [id^='product'] |
| Ends with | [attr$='val'] | [id$='-name'] |
| Contains | [attr*='val'] | [class*='active'] |
| Direct child | parent > child | form > button |
| Descendant | a b | form input |
| Next sibling | a + b | label + input |
| Nth child | :nth-child(n) | li:nth-child(3) |
| First child | :first-child | li:first-child |
| Negation | :not(sel) | input:not([type='hidden']) |
| Pattern | Syntax | Example |
|---|---|---|
| Any tag | //*[@attr] | //*[@data-testid='loginBtn'] |
| Exact text | //tag[text()='val'] | //button[text()='Sign In'] |
| Contains text | //tag[contains(text(),'val')] | //h1[contains(text(),'Welcome')] |
| Starts with attr | //tag[starts-with(@a,'v')] | //*[starts-with(@id,'price')] |
| AND | [@a and @b] | //input[@type='text' and @name='user'] |
| OR | [@a or @b] | //input[@id='user' or @id='email'] |
| Parent | /parent::tag | //input/parent::div |
| Ancestor | /ancestor::tag | //span/ancestor::form |
| Following sibling | /following-sibling::tag | //label/following-sibling::input |
| Preceding sibling | /preceding-sibling::tag | //input/preceding-sibling::label |
| Nth match | (//tag)[n] | (//input)[2] |
| Last match | (//tag)[last()] | (//button)[last()] |
Q: How do you verify your locator is correct before writing code?
A: I test it in DevTools. Open F12, go to Console tab. For CSS: document.querySelector("selector") or document.querySelectorAll("selector").length. For XPath: $x("xpath"). I can also use the Elements tab search (Ctrl+F) and type a selector or XPath directly — it highlights matching elements.
Q: What is a relative locator in Selenium 4?
A: Relative locators (friendly locators) find elements by visual position relative to another element. Selenium 4 provides: above(), below(), toLeftOf(), toRightOf(), and near(). Example: driver.findElement(RelativeLocator.with(By.tagName("input")).below(By.id("username"))) finds the input visually below the username field.
Q: How do you write an XPath for dynamic elements?
A: Use contains() or starts-with() to match the stable part. If the ID is "user-12345" where 12345 changes: //input[starts-with(@id, "user-")]. Or use other stable attributes like name, type, placeholder. Or text-based matching: //label[text()="Email"]/following-sibling::input.
Key Point: CSS for 80% of locators (fast, clean). XPath for text, parent traversal, preceding siblings. Test in DevTools first.
Answer all 5 questions, then submit to see your score.
1. What is the recommended first choice for a locator strategy?
2. Which locator capability does XPath have that CSS selectors do NOT?
3. What does By.cssSelector("[id^='product']") match?
4. Why should you never use absolute XPath in automation tests?
5. How do you test a CSS selector in the browser before coding?