Skip to content

fix: --by cell ranks candidates by grid, re-resolves replaced nodes, names the cover; key reports focused_id - #30

Merged
sanketsudake merged 2 commits into
mainfrom
fix/cell-locator-scope-to-grid
Aug 16, 2026
Merged

fix: --by cell ranks candidates by grid, re-resolves replaced nodes, names the cover; key reports focused_id#30
sanketsudake merged 2 commits into
mainfrom
fix/cell-locator-scope-to-grid

Conversation

@sanketsudake

Copy link
Copy Markdown
Owner

What

Findings from a live Workday timesheet run where fill --by cell "Tue, …" failed as occluded on one column in five, every week, while the other four columns filled fine.

  1. Rank --by cell candidates instead of filtering them.
    The locator picked candidates in document order after a geometric "in this column" test.
    Workday's global "Search Workday" input sits above its Enter Time dialog with its centre inside one day column's tolerance; it comes first in the DOM and is under the modal overlay, so that column resolved to an off-grid, covered input and timed out.
    Now: the header's own grid beats the rest of the page, an unoccluded centre beats a covered one, document order breaks ties.
    Off-grid candidates stay as the last resort (some grids split header and body tables).
  2. Re-resolve when the page replaces the node mid-wait.
    settledNodePoint polled one resolved node until the deadline; a grid that re-renders its row after a commit detaches that node, which then measures 0×0 forever and reads as occluded.
    The geometry probe now reports detached; settledPointFor / coordClickSelector re-resolve the selector on it, and Type, Fill, Key, the pointer verbs and drag targets all go through it.
    Only if the replacement never settles does the caller see a timeout, now with detached: true.
  3. occluded errors name what is on top.
    OccludedError carries the element found at the centre and puts it in the message (its centre is covered by DIV name="modalOverlay", or it measured 0x0).
    The evidence rides in the message because errors cross the daemon RPC as strings and the envelope must read the same on both paths; IsOccluded still matches.
  4. key reports focused_id (DOM id of what has focus after the press) — the disambiguator for grids whose inputs all read as textbox "".
    Additive field.

Tests

  • TestCellAddressingPrefersGridOverOffGridField — reproduces the wrong pick (value lands in the off-grid input) on the old locator.
  • TestCellAddressingReResolvesReplacedNode — commit-veil-then-rebuild fixture; fails on the old code with the exact message seen live.
  • TestOccludedErrorMessage — pins the message format and IsOccluded across a string-only round trip.
  • focused_id asserted in the existing key test.
  • gofmt -l . clean, go vet ./..., go test -race ./... green locally.

Live check

Rebuilt binary against the real grid: a five-column session batch fills clean where the released binary failed the Tue cell.
One residual intermittent post-fill failure (≈1 in 10 on the old binary) was not reproduced after the fix; the new error message will name the cover if it recurs.

Docs

docs/cli-reference.md and skills/drive-chrome-cdp/SKILL.md updated (cell ranking, detached, occlusion evidence, focused_id, Escape inside a dirty dialog, stale-daemon recovery).

…names the cover

Three findings from a live timesheet run where `fill --by cell "Tue, …"`
failed as `occluded` on one column in five, every week, while the other
four columns filled fine.

1. cellLocatorJS picked candidates in document order after a geometric
   "in this column" filter. Workday's global "Search Workday" input sits
   above its Enter Time dialog with its centre inside one day column's
   tolerance; it comes first in the DOM and is under the modal overlay,
   so that column resolved to an off-grid, covered input and timed out.
   Rank candidates instead of filtering: the header's own grid beats the
   rest of the page, an unoccluded centre beats a covered one, document
   order breaks ties. Off-grid candidates stay as the last resort because
   some grids split header and body tables.
   TestCellAddressingPrefersGridOverOffGridField reproduces the wrong pick
   (value lands in the search box) on the old locator.

2. settledNodePoint polled one resolved node until the deadline. A grid
   that re-renders its row after a commit (Workday's does; input ids
   change) detaches that node, which then measures 0x0 forever and reads
   as `occluded`. The geometry probe now reports `detached`, and the new
   settledPointFor / coordClickSelector re-resolve the selector on it;
   Type, Fill, Key, the pointer verbs and drag targets all go through it.
   Only if the replacement never settles does the caller see a timeout,
   now with `detached: true`.
   TestCellAddressingReResolvesReplacedNode models the commit-veil-then-
   rebuild shape and fails on the old code with the exact message seen live.

3. `occluded: true` said nothing about WHAT was on top, so each failure had
   to be reproduced under instrumentation. OccludedError now carries the
   element found at the centre and puts it in the message ("its centre is
   covered by DIV name=\"modalOverlay\"", or "it measured 0x0"); the
   evidence rides in the message because errors cross the daemon as
   strings and the envelope must read the same on both paths. IsOccluded
   still matches. TestOccludedErrorMessage pins the format.

Live-verified on the real grid with the rebuilt binary: a five-column
session batch fills clean where the released binary failed the Tue cell.
…press

`focused` names the focused element by role and accessible name, which is
`textbox ""` for every input in a grid — so a stroke that followed a
coordinate click into the wrong cell was invisible in the envelope and
only showed up in a later value read-back (it did, on a live timesheet:
an `8` typed into Sunday instead of Tuesday).

Add `focused_id`: `document.activeElement.id` when the element has one,
read best-effort like `focused` and omitted otherwise. Additive field, no
change to existing shape.
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