docs(locators): publish generated-code locator policy - #989
Conversation
Document the three-tier SHAFT locator ladder for generated and repository code, and replace Smart Locator examples that the codegen guardrails reject.
MohabMohie
left a comment
There was a problem hiding this comment.
Independent adversarial review
Confirmed head 137afc1b263bd71e0f0cb8d5ac83caa9c4461012 on ShaftHQ/shafthq.github.io#989. Read the full diff against SHAFT #5147. This is a comment review only. Do not merge.
The locator-policy additions on docs/testing/web.mdx, docs/agentic/capture.md, docs/agentic/mcp.mdx, docs/agentic/intellij.md, and docs/features/test-automation-pillars.mdx match the engine ladder (unique author-written id via the SHAFT builder, then ARIA role, then native relative xpath). Inventory is on SHAFT #5147. #5150 / #5151 / #5152 are correctly left out. No SHAFT_ENGINE files were touched.
The PR still does not finish the confirmed locator-policy gap.
F1 — leftover Smart Locator teaching on pages this PR edited
docs/reference/actions/GUI/Element_Identification.md adds a warning that Smart Locators are throwaway-only, then keeps a complete SmartLocatorsExample.java (:766) and this tip (:779):
Smart locators are the most resilient option for forms
That tip is the opposite of the generated/repository policy.
docs/reference/actions/GUI/Locators_And_Self_Healing.md now owns the official policy (:12), then the Smart Locators section (:186) still ships a login snippet using inputField / clickableField and ranks them High against ID Low (:207). Readers copy the table and the biggest code block, not the warning five screens up.
This is the same leftover-teaching failure mode as SHAFT #4239 (policy stated, Smart Locators still recommended in the copy-paste surface). Spec: do not teach inputField / clickableField as generated or repository code.
Required: delete or clearly fence those examples as human-exploration-only, remove the "most resilient" tip, and stop ranking Smart Locators above author-written ids.
F2 — do not close SHAFT #5147
PR body says Closes ShaftHQ/SHAFT_ENGINE#5147. #5147 acceptance allows leftover gaps only when each leftover action has its own issue. F1 is the original confirmed gap (Smart Locator section / maintainability teaching) still open and not covered by #5150, #5151, or #5152.
Drop the closing keyword until F1 is fixed or ticketed. A locator-only docs PR must not close the full retroactive-sync subtask while that contradiction remains.
F3 — official policy page is missing the recycled-id ban
docs/testing/web.mdx:75 lists framework-recycled ids (:r1:, mat-input-3, cdk-overlay-0, …). The page this PR calls official SHAFT-GUIDE policy (Locators_And_Self_Healing.md:12) does not. Engine source is chaos-engine/profiles/shaft/references/shaft-mastery/locator-healing.md:14. A reader who only opens the canonical section can hasId("mat-input-3") and think they followed the guide.
Copy the recycled-id exclusion onto the canonical section.
Not findings
- #5150 iOS/Windows, #5151 IntelliJ screenshots, #5152 AGENTS.md path — ticketed, out of this PR.
- Spot-check of the inventory "covered, no change" rows (modules, JDK 25,
healing.strategy/pilot.ai.enabled,AiExecutionService) still have guide text. I did not find a separate unsticketed public surface beyond F1/F3. - Capture / MCP / IntelliJ / web / pillars examples no longer emit
inputField/clickableFieldor raw locator factories as generated code. - Human steps + AI codegen commands are on the canonical policy page. No new screenshots, as claimed.
Verdict: do not merge. Do not close #5147. Fix F1 and F3 on this PR, or ticket F1/F3 and remove Closes.
## Summary Require a companion user-guide PR on `ShaftHQ/shafthq.github.io` `master` for every user-facing SHAFT behavior change. The companion PR must include a description of the change, screenshots where a human sees UI, human-facing instructions, and AI-supported details (locator policy, replay-proven snippets, properties, exact commands). Discover the docs root; never a fixed sibling path and never `localRoot` in `profile.json`. Closes #5146. Related to #5145. ## Checks - RED: `py -3 -m unittest tests.scripts.test_chaos_engine_portable_core.ChaosEnginePortableCoreTest.test_shaft_user_facing_changes_require_companion_docs_prs` failed with 18 `assertIn` misses (required sentences absent). - GREEN: same focused test `OK`; full `py -3 -m unittest tests.scripts.test_chaos_engine_portable_core` — 22 tests `OK`. - `py -3 scripts/ci/validate_documentation_boundaries.py` — valid (586 tracked Markdown files). - `py -3 scripts/ci/validate_agent_guidance.py` — budgets, routing, references valid. - `py -3 scripts/ci/validate_agent_setup.py --skip-external` — guidance/docs checks pass; remaining `memory-untracked` is leftover Soup Memory objects in this assigned worktree (out of scope; not committed). - `git diff --check` clean on the staged files. This is agent-guidance policy, not a public user-facing SHAFT product change. The retroactive public-guide sync is [shafthq.github.io#989](ShaftHQ/shafthq.github.io#989). ## Continuation - Head: `f487a62ed40e4c64a9ae299d79afcfd6eb0bdb5a` - State: policy pins landed; Memory gotcha for pin-wrap committed. Companion docs PR ShaftHQ/shafthq.github.io#989 is open. Do not merge; orchestrator reviews both PRs. - Blockers: none for this PR. Assigned worktree still has untracked Soup Memory files that must stay unstaged. - Next action: independent review of this PR and docs PR 989.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
shaft-engine | b83a1e9 | Commit Preview URL Branch Preview URL |
Aug 18 2026, 03:44 PM |
Rewrite Element Identification Smart Locators as human-exploration only and drop SmartLocatorsExample.java plus the most-resilient-forms tip. Align the Locators and Self-Healing ranking table with the three-tier generated policy, and copy the framework-recycled id ban onto the official policy section. Closes #990. Closes #991. Related to ShaftHQ/SHAFT_ENGINE#5147.
MohabMohie
left a comment
There was a problem hiding this comment.
Independent adversarial review
Confirmed live head 53c0ae6c75d8933b95d9853d910ddcd3156ef79e on #989 (prior review was 137afc1b263bd71e0f0cb8d5ac83caa9c4461012). Scoped to the leftover commit plus whether prior F1/F3 are fixed. Comment review only. Do not merge.
Prior findings
Prior F1 — leftover Smart Locator teaching — FIXED
docs/reference/actions/GUI/Element_Identification.md no longer ships SmartLocatorsExample.java or the tip that Smart Locators are the most resilient form strategy. The remaining snippet is ThrowawayExploration.java and is labeled human-exploration only. docs/reference/actions/GUI/Locators_And_Self_Healing.md ranking table no longer ranks Smart Locator High against ID Low; the Smart Locator row is now "Human exploration only; never generated or repository code." #990 acceptance is met.
Prior F3 — recycled-id ban on official policy — FIXED
Locators_And_Self_Healing.md:19-20 now names :r1:, mat-input-3, cdk-overlay-0, ember1234, j_idt42, ctl00_..., and sc-bdVaJa. That list matches docs/testing/web.mdx:77-79. #991 acceptance is met.
Prior F2 — do not close SHAFT #5147 — FIXED
PR body and leftover commit say Related to ShaftHQ/SHAFT_ENGINE#5147. closingIssuesReferences is only docs #990 and #991. Remaining leftovers #5150, #5151, #5152, and #992 stay listed and open.
New findings
F1 — leftover ranking table teaches hasText instead of hasNormalizedText
Locators_And_Self_Healing.md:206 (this leftover commit) uses hasRole(Role.BUTTON).hasText("Log In") as the official second-rung example.
Same-page official policy (:21-22) and engine codegen (shaft-capture/.../LocatorPolicy.java:141-142) emit hasNormalizedText. hasText is exact raw string-value ([.=...]); hasNormalizedText is normalize-space(.). Readers copying the table this commit just rewrote will not match generated code or the policy section above it.
Non-blocking. Do not keep #990 or #991 open for this. Optional follow-up: swap the table cell to hasNormalizedText. web.mdx:80 and flakiness.mdx:44 already used the older hasText example; those are first-commit leftovers, not this commit.
Not findings
- #992 Best Practices /
LoginPage.java/ rawBy.idranking remains. Ticketed. Correctly not folded into a SHAFT #5147 close. - #5150 iOS/Windows, #5151 IntelliJ screenshots, #5152 AGENTS.md path — ticketed, out of this PR.
- Remaining throwaway
inputField/clickableFieldsnippets are what #990 asked to keep. - Claimed checks reproduced on the worktree at this SHA:
node tests/docs-quality.test.jspassed;node scripts/check-doc-duplicates.mjspassed;git diff --checkclean. Those checks do not pin leftover Smart Locator teaching. - No
Closes ShaftHQ/SHAFT_ENGINE#5147.
Verdict: Prior F1/F3 fixed. Do not merge. Do not close SHAFT #5147. #990 and #991 may close with this PR. Optional: fix new F1 hasText or leave it with the #992-class leftover.
| | XPath | `//button[@data-testid='login']` | Medium | | ||
| | Smart Locator | `clickableField("Log In")` | High | | ||
| | Author-written id | `SHAFT.GUI.Locator.hasAnyTagName().hasId("login-submit").build()` | First, when unique and not recycled | | ||
| | ARIA role | `SHAFT.GUI.Locator.hasRole(Role.BUTTON).hasText("Log In").build()` | Second | |
There was a problem hiding this comment.
…ocumented-main-5147
## Summary Closes #992 Closes #993 Related to ShaftHQ/SHAFT_ENGINE#5147. Leftover teaching after #989 still ranked raw `By.id` / CSS over native relative xpath, and official locator-strategy pages taught `hasText` as the generated second rung. - Best Practices and titled `LoginPage.java` samples now follow unique author-written id via `hasAnyTagName().hasId(...)`, then ARIA role with `hasNormalizedText`, then native relative `By.xpath(...)` only. - Official first-link ladder on `docs/testing/web.mdx` now uses `hasNormalizedText`. - `test-automation-pillars.mdx` login click uses `hasNormalizedText`. - Titled `LoginPage.java` samples on `Solution_Design.md` use the SHAFT locator builder. - Element_Identification leftover catalog / `hasId(` start / xpath-by-id / dynamic CSS samples now follow generated policy. - Titled `ARIALocators.java` and `flakiness.mdx` Semantic Locators ladder / `SemanticLocators.java` now use `hasNormalizedText`. - Raw Selenium `By` stays a reference for existing locators, not the generated-code default. - Smart Locators stay human-exploration only. - Ranking table now matches `LocatorPolicy` / the official policy section: `hasNormalizedText`. - Method catalog still documents `hasText` as an existing builder method. - `tests/docs-quality.test.js` fails if any public docs page teaches `hasRole(...).hasText(` as the generated form, and binds the titled `ARIALocators.java` / `SemanticLocators.java` fences. ## Checks - RED then GREEN: `node tests/docs-quality.test.js` - Repo-wide hunt: `hasRole(.*).hasText(` leftovers remain only in the quality-test assertion strings. - Isolated worktree from fetched PR branch (`docs/locator-leftovers-992-993`). Primary checkout was not used. - No browsers. No new screenshots. No SHAFT_ENGINE code edits. ## Continuation - Head: `062bf8d8b831603396ca25d19b2a626429ea2a0c` - State: Review 4963577044 F1-F2 patched on this SHA. Writer stopped. - Blockers: none for this patch. Do not merge until orchestrator review of this exact head. - Next action: independent review of `062bf8d8b831603396ca25d19b2a626429ea2a0c`. Writer does not merge.
Summary
Retroactively sync the user guide with the official generated/repository locator policy already on SHAFT
main: unique author-written id via the SHAFT locator builder, then ARIA role, then native relative xpath only. Smart Locators stay human-exploration only. Capture, MCP, IntelliJ, web, flakiness, and pillars examples no longer teachinputField/clickableFieldor raw locator factories as generated code.Review leftovers on this PR:
Related to ShaftHQ/SHAFT_ENGINE#5147. Related to ShaftHQ/SHAFT_ENGINE#5145.
Closes #990. Closes #991.
Remaining gaps (not in this PR):
By.id/ CSS over native relative xpath, andLoginPage.javastill uses rawBy.id/By.cssSelector.Checks
node tests/docs-quality.test.js— Documentation quality checks passed.node scripts/check-doc-duplicates.mjs— no duplicated long-form blocks.git diff --checkclean.Continuation
53c0ae6c75d8933b95d9853d910ddcd3156ef79eC:\Users\Mohab\.grok\worktrees\shafthq.github.io-5147. Primary checkout ondocs/mobile-ios-windows-4977was not written.