Skip to content

docs(locators): align leftover ranking with generated policy - #994

Merged
MohabMohie merged 3 commits into
masterfrom
docs/locator-leftovers-992-993
Aug 18, 2026
Merged

docs(locators): align leftover ranking with generated policy#994
MohabMohie merged 3 commits into
masterfrom
docs/locator-leftovers-992-993

Conversation

@MohabMohie

@MohabMohie MohabMohie commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

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.

@MohabMohie

Copy link
Copy Markdown
Contributor Author

Orchestrator: writer stopped. HEAD 58f5032 closes #992 and #993. Independent review dispatched on this exact SHA. Do not merge until that review returns zero blocking findings. Docs repo merge may need --admin; orchestrator will do that only after zero blocking.

@MohabMohie MohabMohie left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review

Bound to 58f5032. Event is COMMENT only. Do not merge.

Writer claim checked: Element_Identification.md + LoginPage.java + Locators_And_Self_Healing.md ranking table, with RED then GREEN
ode tests/docs-quality.test.js, closing #992 and #993.

What actually landed: three files. Best Practices and the LoginPage.java snippet inside Element_Identification.md were rewritten. The ranking table now shows hasNormalizedText. I ran
ode tests/docs-quality.test.js on this HEAD: it printed Documentation quality checks passed. Overlaying this HEAD test on the pre-change pages fails first on Prefer ID locators, so the new asserts are RED against those exact strings. That is not enough to close the leftover class.

Engine contract used as the spec: LocatorPolicy.java emits hasAnyTagName().hasId(...), then hasRole(...).hasNormalizedText(...), then native relative By.xpath(...) only. Official generated/repo policy on this same HEAD still says that. docs/testing/web.mdx is the page Element_Identification tells readers to start with.


F1 Fail / Blocking

Where: PR body, commit message Closes #992 / Closes #993; gh pr view --json files is only docs/reference/actions/GUI/Element_Identification.md, docs/reference/actions/GUI/Locators_And_Self_Healing.md, ests/docs-quality.test.js. No LoginPage.java file.
Scenario: A closer treats #992 and #993 as done because the PR says Closes. A reader searches for LoginPage.java and still copies raw By.id.
Evidence: #992 acceptance is Best Practices plus the Element_Identification page-object form. Those two spots in this file did change (Element_Identification.md:758-767, :821-824). Credit stops there. #992's own problem statement also named Supported Locator Types ranking raw By.id first; the catalog still does (:22-27). #993 acceptance is table vs official policy on Locators_And_Self_Healing. The table line changed (Locators_And_Self_Healing.md:206). The official user-facing ladder on docs/testing/web.mdx:80 still teaches hasText("Create Account") and the file contains zero hasNormalizedText. docs/reference/guides/Solution_Design.md:18-26 is still a titled LoginPage.java sample with By.id("username").
Class: Credit-not-in-diff / incomplete close.
Fix: Do not close #992 or #993 from this SHA. Either expand the PR to the official web.mdx ladder and the remaining titled LoginPage.java samples, or drop Closes and open one standalone leftover issue per remaining site. The snippet rewrite in Element_Identification is real; the close credit is not.

F2 Fail / Blocking

Where: docs/testing/web.mdx:79-80; docs/reference/guides/Solution_Design.md:18-26; docs/features/test-automation-pillars.mdx:159; docs/reference/actions/GUI/Element_Identification.md:14-16 (sends readers to web.mdx first).
Scenario: New-test author follows Element_Identification Overview to the web locator strategy, copies the official second rung, and ships hasText while codegen emits hasNormalizedText. Same leftover #993 named, on a more important page, not in the diff.
Evidence: HEAD web.mdx:80 is SHAFT.GUI.Locator.hasRole(Role.BUTTON).hasText("Create Account").build().
g hasNormalizedText docs/testing/web.mdx is empty. Solution_Design.md POM sample still recommends By.id as the default page-object form. est-automation-pillars.mdx:159 is a generated-looking login click with hasText("Log in"). None of these files are in the PR. I searched ShaftHQ/shafthq.github.io issues for this leftover class; only #992/#993 are open, both scoped to the two edited pages.
Class: Missing-adoption leftover. Same observable contract as #992/#993, sibling official pages not updated, no test flags the omission.
Fix: Change web.mdx:80 to hasNormalizedText. Update or fence every titled LoginPage.java sample that still teaches raw By.id as the generated/repo form. Do not treat #989 follow-up leftovers as done while the first-link official ladder still disagrees with LocatorPolicy.

F3 Fail / Blocking

Where: docs/reference/actions/GUI/Element_Identification.md:24-27, :67-68, :119, :187, :775-781.
Scenario: Reader sees the new fence at :20, then immediately copies numbered example 1 By.id("username") or the builder start SHAFT.GUI.Locator.hasId("submit-btn").build().
Evidence: :24 still says ID is "the most reliable and fastest method when available" — the same Prefer-ID ranking with different words. :27 is still By.id("username"). :67-68 still show By.xpath("//input[@id='username']") after :65 says use xpath only when there is no unique author-written id. :119 and :187 still start the builder at SHAFT.GUI.Locator.hasId(...) instead of the official hasAnyTagName().hasId(...) emission. Dynamic locators still lead with By.cssSelector. Official ban is SHAFT.GUI.Locator.id/name/cssSelector/className/tagName(...) and SHAFT.GUI.Locator.xpath(...); those raw factories are not newly introduced. The leftover is worse: the page this PR claims to align still teaches raw By.id / hasId(...) start / xpath-by-id as the samples.
Class: Same-page policy contradiction / non-official factory samples.
Fix: Keep raw Selenium By only behind an explicit existing-locator fence. Generated/repo samples on this page must be hasAnyTagName().hasId(...), then hasRole(...).hasNormalizedText(...), then relative By.xpath(...) that does not target an id that should have taken tier 1.

F4 Fail / Blocking

Where: ests/docs-quality.test.js:268-307.
Scenario: Demonstration 1 — keep :24 "most reliable and fastest" and the By.id catalog; test stays green. Demonstration 2 — leave web.mdx:80 as hasText; test stays green. Demonstration 3 — change loginButton to hasRole(...).hasText("Log In") while leaving hasAnyTagName().hasId("username"); test stays green. Demonstration 4 — add hasRole(Role.BUTTON).hasNormalizedText("Log In") anywhere on Locators_And_Self_Healing.md and restore the table to hasText; the page-wide positive assert still passes. The negative table-row regex does bind that one markdown row (I confirmed it matches master Locators_And_Self_Healing.md:206 and not HEAD).
Evidence: Test only reads the two files the writer already edited. Asserts are exact-phrase locks (Prefer ID locators, Avoid XPath when possible, CSS selectors are generally faster, private final By loginButton = By.cssSelector). They do not assert loginButton uses hasRole + hasNormalizedText. They do not read docs/testing/web.mdx, Solution_Design.md, or other LoginPage.java fences. HEAD still contains "most reliable and fastest" and SHAFT.GUI.Locator.hasId(. History is one commit; there is no RED commit, only a property I reproduced by overlaying the new test on the old pages.
Class: Broken-verification / missing-adoption gap. Phrase lock, not leftover-class coverage.
Fix: Pin the official ladder on docs/testing/web.mdx to hasNormalizedText. Fail if Element_Identification still ranks raw ID as fastest or still shows catalog By.id / Locator.hasId( as the generated form. Assert the LoginPage loginButton line. Scan titled LoginPage.java snippets. A synonym of Prefer ID must fail.


Narrow credit (not a close): Best Practices list and the Element_Identification LoginPage snippet no longer contain the three banned phrases or By.cssSelector for loginButton. Ranking table line now matches LocatorPolicy on that one page.

Merge: no. Blocking leftovers remain on the official first-link ladder and on the same page this PR claims to fix. Independent review of 58f5032 is COMMENT only.

@MohabMohie

Copy link
Copy Markdown
Contributor Author

Orchestrator: independent review confirmed SHA 58f5032. Merge blocked (F1–F4: leftover official pages + credit-not-in-diff + thin quality test). New writer dispatched on this PR. Do not merge this SHA.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 18, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
shaft-engine 062bf8d Commit Preview URL

Branch Preview URL
Aug 18 2026, 04:59 PM

@MohabMohie

Copy link
Copy Markdown
Contributor Author

Writer patched review 4963447427 (F1-F4) on this branch.

New HEAD: 7cf94527774d9a1170218d4caadae905f3945384

Writer stops. No merge. No approve.

@MohabMohie MohabMohie left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review

Bound to 7cf94527774d9a1170218d4caadae905f3945384. Event is COMMENT only. Do not merge.

Isolated checkout: %TEMP%\shaft-docs-994-review2 at that exact SHA. node tests/docs-quality.test.js printed Documentation quality checks passed. Engine contract used as spec: LocatorPolicy.java emits hasRole(...).hasNormalizedText(...) for a verified named role (shaft-capture/src/main/java/com/shaft/capture/generate/LocatorPolicy.java:139-142).

Prior F1–F4 named sites: fixed

  • docs/testing/web.mdx:80 official second rung is hasNormalizedText("Create Account").
  • docs/features/test-automation-pillars.mdx:159 login click is hasNormalizedText("Log in").
  • docs/reference/guides/Solution_Design.md titled LoginPage.java / FluentLoginPage.java use hasAnyTagName().hasId(...).
  • docs/reference/actions/GUI/Element_Identification.md dropped Prefer-ID / "most reliable and fastest", catalog By.id("username"), Locator.hasId( start, xpath-by-id, and DynamicLocators CSS lead. Best Practices now match the three-tier ladder. Smart Locators stay fenced as throwaway.
  • docs/reference/actions/GUI/Locators_And_Self_Healing.md:206 ranking table is hasNormalizedText.
  • tests/docs-quality.test.js now reads those leftover official pages and locks the strings the last review named.
  • #992 / #993 acceptance text is met on the pages those tickets named.

That is not enough to merge. Official pages still teach hasText as the generated ARIA matcher. Repo-wide hasRole(...).hasText( now remains only on the two sites below. No open issue covers them (only #992/#993, both page-scoped).


F1 Fail / Blocking

Where: docs/reference/actions/GUI/Locators_And_Self_Healing.md:61-75 (ARIALocators.java); docs/testing/flakiness.mdx:41-65 (SemanticLocators.java).
Scenario: Reader follows the official locator policy page's ARIA section, or the testing "Semantic Locators" ladder that restates generated/repo policy, copies the first working sample, and ships hasText while codegen emits hasNormalizedText.
Evidence: Same HEAD policy section (Locators_And_Self_Healing.md:21-22) and ranking table (:206) say hasNormalizedText. Forty lines later the titled generated/repo ARIA sample is SHAFT.GUI.Locator.hasRole(Role.BUTTON).hasText("Submit").build(). The tip at :73-75 tells generated/repo authors to chain hasRole(...) with text and does not name hasNormalizedText. flakiness.mdx:37-45 restates the generated locator policy, then lists the second rung as hasRole(Role.BUTTON).hasText("Sign in"). Titled SemanticLocators.java at :61 repeats it. This file is not in the PR. rg of hasRole\(Role\.[A-Z]+\)\.hasText\( on docs/ hits only these two pages.
Class: Missing-adoption leftover. Same official-matcher contract as #993, now on the first copy-paste ARIA sample of the official policy page this PR edited, plus a sibling official testing page. No test flags either site.
Fix: Change those official generated/repo samples to hasNormalizedText. Keep hasText only in the builder method catalog / existing-API list, not as the official second-rung matcher. Open one leftover issue if this SHA will not expand; do not treat the leftover class as exhausted because #992/#993 acceptance is met.

F2 Fail / Blocking

Where: tests/docs-quality.test.js:268-280, :351-353, :384-393.
Scenario: Demonstration 1 — leave ARIALocators.java as hasText("Submit"); current test stays green (observed: this HEAD already did that and printed passed). Demonstration 2 — leave flakiness.mdx as hasText("Sign in") / hasText("Apply filter"); test stays green because officialLocatorPages does not read that file. Demonstration 3 — restore the ranking table to hasText("Log In") while adding hasRole(Role.BUTTON).hasNormalizedText("Log In") anywhere else on the page; the page-wide positive still passes and only the exact table-row negative would fail.
Evidence: officialLocatorPages is web.mdx, pillars, Solution_Design, Element_Identification, Locators_And_Self_Healing. web/pillars negatives are exact-phrase locks (hasText("Create Account"), hasText("Log in")), not a leftover-class scan. Locators_And_Self_Healing only bans the markdown table row ARIA role | \SHAFT.GUI.Locator.hasRole(Role.BUTTON).hasText("Log In").build()`. It never asserts the titled ARIALocators.javafence. F4's requested named-site pins landed; the leftover class still has no failing check. **Class:** Broken-verification / missing-adoption gap. Phrase lock, not official-matcher coverage. **Fix:** Fail if an official locator-strategy page teacheshasRole(...).hasText(as the generated/repo form. Includedocs/testing/flakiness.mdx. Bind the ARIALocators.java/SemanticLocators.java` fences, not only the ranking-table row.


Narrow credit: Prior blocking F1–F4 named sites on this SHA are actually in the diff and match LocatorPolicy. #992 Best Practices / catalog / page-object form and #993 table-vs-policy acceptance are met. Closes #992 / Closes #993 may stay for those tickets. They do not cover F1/F2 here.

Non-blocking hunt result: No remaining Prefer-ID / "most reliable and fastest" ranking. Action-API samples still use raw By.id (Element_Actions, TestData, Test_Structure, JUnit, etc.); those do not rank locators. Solution_Design.md titled InlineTest.java still uses By.id behind an anonymous/prototype warning — not the official generated form.

Merge: no. Zero blocking required. Independent review of 7cf94527774d9a1170218d4caadae905f3945384 is COMMENT only.

@MohabMohie

Copy link
Copy Markdown
Contributor Author

Orchestrator: review of 7cf9452 is blocked (F1–F2: ARIALocators.java and flakiness.mdx still teach hasRole().hasText; quality test missed them). New writer dispatched to fix all official hasRole().hasText leftovers and tighten the test. Do not merge this SHA.

Closes #992
Closes #993
Related to ShaftHQ/SHAFT_ENGINE#5147.

Official ARIALocators.java and flakiness SemanticLocators samples now
use hasNormalizedText as the generated second rung. The quality test
fails if any public docs page teaches hasRole(...).hasText( and binds
those titled fences.
@MohabMohie

Copy link
Copy Markdown
Contributor Author

Writer patched review 4963577044 (F1-F2) on this branch.

New HEAD: 062bf8d8b831603396ca25d19b2a626429ea2a0c

  • Official leftovers of hasRole(...).hasText( now use hasNormalizedText: titled ARIALocators.java on Locators_And_Self_Healing.md, plus the Semantic Locators ladder and titled SemanticLocators.java on docs/testing/flakiness.mdx. The generated/repo tip now names hasNormalizedText.
  • Method catalog still documents hasText as an existing builder method.
  • tests/docs-quality.test.js now fails if any public docs page teaches hasRole(...).hasText( as the generated form, and binds those titled fences.
  • Repo-wide hunt after the fix: leftover form remains only in the quality-test assertion strings.
  • RED then GREEN: node tests/docs-quality.test.js.
  • Closes Align Element Identification best practices with generated locator policy #992 and Locator ranking table should show hasNormalizedText not hasText #993 kept: those tickets' acceptance stays met; this pass also covers the leftover official-matcher class they did not name.

Writer stops. No merge. No approve.

@MohabMohie MohabMohie left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independent adversarial review

Bound to 062bf8d8b831603396ca25d19b2a626429ea2a0c. Event is COMMENT only. Do not merge.

Isolated checkout: %TEMP%\shaft-docs-994-review3 at that exact SHA. node tests/docs-quality.test.js printed Documentation quality checks passed. Engine contract used as spec: LocatorPolicy.java emits hasRole(...).hasNormalizedText(...) for a verified named role (shaft-capture/src/main/java/com/shaft/capture/generate/LocatorPolicy.java:139-142).

Prior blocked-SHA F1–F2: fixed

  • docs/reference/actions/GUI/Locators_And_Self_Healing.md:65 titled ARIALocators.java is hasRole(Role.BUTTON).hasNormalizedText("Submit").
  • Tip at :73-75 now names hasNormalizedText, hasAttribute, or context.
  • docs/testing/flakiness.mdx:44 ladder and :61 titled SemanticLocators.java use hasNormalizedText.
  • tests/docs-quality.test.js:283-289 walks every public docs page and fails hasRole(...).hasText(.
  • Same file binds the titled ARIALocators.java / SemanticLocators.java fences (:405-437).
  • Diff vs blocked 7cf94527774d9a1170218d4caadae905f3945384 is exactly those three files.

Claims checked

  • Repo-wide rg hasRole\(.*\)\.hasText\( on this HEAD hits only the three quality-test assertion strings (tests/docs-quality.test.js:288, :419, :436).
  • No official leftover Prefer-ID / "most reliable and fastest" / "Avoid XPath when possible" / "CSS selectors are generally faster" ranking in docs/.
  • No Locator.hasId( start. SHAFT.GUI.Locator.id/xpath(...) remains only in "never emit" prose.
  • #992 Best Practices / catalog / page-object form and #993 table-vs-policy acceptance remain met. Closes #992 / Closes #993 stay honest.

Findings

Zero blocking. No F-items.

Verification-gap demonstrations that now fail: restore ARIALocators.java or SemanticLocators.java to hasRole(...).hasText(, or restore the ranking-table hasText("Log In") row. The public-docs scan and the titled-fence pins would throw. I did not mutate the tree; the regex is the same leftover class the last review named.

Non-blocking hunt

hasText remains in the builder method catalog, Shadow DOM / axis samples, and Playwright_Backend.md PortableLocator.java (hasTagName("button").hasText("Save")). Those are existing-API / portable-builder docs, not hasRole(...).hasText( as the generated second rung. Action-API pages and Solution_Design.md InlineTest.java still use raw By.id behind action-syntax or prototype warnings, not official ranking.

Merge: allowed on blocking count (zero). This review is COMMENT only and does not merge.

@MohabMohie
MohabMohie enabled auto-merge August 18, 2026 17:05
@MohabMohie
MohabMohie merged commit 91c1012 into master Aug 18, 2026
6 of 7 checks passed
@MohabMohie
MohabMohie deleted the docs/locator-leftovers-992-993 branch August 18, 2026 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Locator ranking table should show hasNormalizedText not hasText Align Element Identification best practices with generated locator policy

1 participant