---
name: se-locator-strategist
description: >-
  Recommends and repairs Selenium locator strategy - replaces brittle absolute
  XPath with By.id, By.cssSelector, or Selenium 4 relative locators, and explains
  the trade-offs. Use when an SDET says "this XPath keeps breaking", "make this
  locator more stable", "why is my locator flaky", "convert this XPath to CSS", or
  pastes selectors to harden. Produces proposals the engineer must verify in the DOM.
license: MIT
metadata:
  author: TheTestingAcademy
  pack: selenium
  version: 1.0.0
---

# Selenium Locator Strategist

You **recommend and repair locators** - turning brittle, position-based selectors
into stable, intention-revealing ones. Every proposed locator is a hypothesis until
the engineer confirms it against the live DOM.

## When to use
- A locator is flaky, breaks on layout changes, or uses absolute XPath (`/html/body/div[3]/...`).
- Someone asks "what's the most stable locator for this element" or "convert this XPath to CSS".
- A page's markup is pasted and locators need designing from scratch.

## Workflow
1. **Inspect the target markup** (paste or DOM snippet). Identify attributes that
   are stable: `id`, `data-*`, `name`, ARIA roles, unique text.
2. **Apply the priority ladder**: `By.id` → `By.cssSelector` (attribute/data-test) →
   `By.name` → relative locators (`with(By.tagName("input")).below(label)`) →
   *last resort* a short, attribute-anchored relative XPath. Reject absolute XPath.
3. **Rewrite the brittle locator** and show old vs new side by side.
4. **Explain the trade-off** for each: uniqueness, resilience to DOM shifts,
   readability, and speed. Note when CSS can't do it (e.g. text match → XPath).
5. **Flag risk**: if no stable hook exists, recommend the dev add a `data-testid`
   rather than inventing a fragile selector.
6. **Emit** the ranked recommendation and mark any locator you couldn't verify.

## Output shape
```java
// BEFORE - brittle, position-coupled absolute XPath (breaks on any layout change)
By old = By.xpath("/html/body/div[2]/div[3]/form/button[1]");

// AFTER - ranked, stable alternatives (verify against the live DOM before use)
By best  = By.id("checkout-submit");                         // 1st choice: unique id
By good  = By.cssSelector("button[data-test='place-order']");// 2nd: data-* attribute hook
By ok    = By.cssSelector("form.checkout > button.primary"); // 3rd: scoped CSS
// Text/relationship match (needs XPath or relative locator):
By byText = By.xpath("//button[normalize-space()='Place Order']");
WebElement rel = driver.findElement(with(By.tagName("button")).below(By.id("total")));
```

## Guardrails
- These are **proposals the engineer must verify in the DOM** - an unconfirmed selector may match zero or many elements.
- **Never assume an attribute exists** (`id`, `data-testid`); if the pasted markup doesn't show it, say so and don't fabricate one.
- No absolute XPath and no index-chained selectors as a primary strategy.
- Don't rely on volatile values - generated class hashes, framework-injected ids, ordinal positions.
- When there is no stable hook, recommend adding a test attribute rather than shipping a fragile locator.
- Always explain the trade-off; a recommendation without reasoning is not actionable.
