Skip to content

focus_on: no check for an element without a role and a name - #1595

Merged
abrichr merged 2 commits into
mainfrom
fix/focus-on-needs-a-name
Oct 28, 2026
Merged

abrichr merged 2 commits into
mainfrom
fix/focus-on-needs-a-name

Conversation

@abrichr

@abrichr abrichr commented Oct 28, 2026

Copy link
Copy Markdown
Member

This is the follow-up the #1579 review asked for, stacked on #1579. It retargets to main when #1579 merges.

Problem

A focusable element with no role or name, but with a bare id or testid, still got an id-only focus_on check. Two probes from the review passed on the wrong element:

  • a plain div host whose closed shadow root holds the real focus (the page sees only the host and its id);
  • an unnamed tabindex div whose unlisted id shifts by one render.

Change

  • The compiler (_focus_postcondition) creates no focus check for an element without a role and a non-empty accessible name, whatever its id or testid. The step stays vacuous and is refused as before. When a testid or id is used, the role and name are always bound with it.
  • focus_identity_is_specific agrees: an id or testid postcondition without a role and name asserts nothing and never passes. focus_on: check who has the focus after a key that changes nothing visible #1579 isn't released, so no existing bundle depends on the old rule.
  • Not done: ignoring trailing counts in a name, such as "Save (3)", when a testid is also bound. A name that changes still fails closed, so it can be added later without loosening anything.

Tests

In tests/test_focus_on_postcondition.py, 33 tests pass:

  • A unit case: an id or testid without a role and name makes no check, and such a postcondition stays vacuous.
  • In real Chromium:
    • a plain host with a closed shadow root, focused on its inner button, gets no check;
    • an unnamed div with a shifting id gets no check.

ruff, ruff format, mypy and strict mypy are clean.

🤖 Generated with Claude Code

An id or testid alone no longer makes a focus check: an unnamed focusable element (a bare tabindex div, a plain host whose closed shadow root holds the real focus) gets none, and the step stays vacuous, refused as before. focus_identity_is_specific agrees: an id or testid postcondition without a role and name asserts nothing and never passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@abrichr

abrichr commented Oct 28, 2026

Copy link
Copy Markdown
Member Author

AI review (coordinator): approved. A strict tightening: an id or testid focus check now requires a role and a non-empty name, otherwise the step stays vacuous and refused, so the two review probes (a closed shadow root on a plain host, an unnamed div with a shifting id) can't pass. Arm once it's retargeted to main after #1579 merges, not while it's stacked.

Base automatically changed from feat/focus-on-postcondition to main October 28, 2026 21:34
@abrichr
abrichr enabled auto-merge October 28, 2026 21:37
@abrichr
abrichr merged commit 072ec5c into main Oct 28, 2026
41 checks passed
@abrichr
abrichr deleted the fix/focus-on-needs-a-name branch October 28, 2026 23:53
abrichr added a commit that referenced this pull request Oct 29, 2026
Bumps openadapt-flow to 2.4.1 (pyproject, __version__, the editable root in
uv.lock) and writes the 2.4.1 changelog for everything user-visible merged
since openadapt-flow-v2.4.0: #1593 (Windows config pin), #1594 (product code
no longer imports the benchmark package), #1569 (div, grid and card worklist
rows), #1539 (fault gate per class) and #1579/#1595 (focus_on). Regenerates
llms-full.txt.

Merging this publishes 2.4.1 through release-package.yml once main's
Packages run for this commit passes.
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.

1 participant