Find a waited selector in the frames a page shows
Merged
YO
10d ago+162+162+012345678901234567890123456789-28-28-01234567890123456789
Summary
On a public bid-information site built of framesets, wait: {selector} never held. In a browser session on its search page:
{"wait": {"selector": "select[name=ejMaxDisplayRowCount]"}, "timeout": "5s"}
-> wait failed: Uncaught (in promise) Error: waitForSelector: Timeout 5000ms exceeded waiting for "select[name=ejMaxDisplayRowCount]" to be visible
The select was on screen, in a frame. #3429 made expect/when {text} and {selector} read the frames a page shows; wait: {selector} and an upload without into still looked in the top document only.
Root cause
WaitForSelectorhanded a CSS selector to the runtime'spage.waitForSelector, which resolves a plain CSS selector in the main frame only. Frames are reached only through>>hops or a deep XPath.uploadwithoutintocountedxpath=//input[@type=file]through the runtime, which also evaluates in the main frame only. So a frameset page's only file input was reported aserrNoFileInput.
Fix
shownDocuments(from #3429) now also returns, for each document, the XPath of the frame holding it, in the runtime's deep-XPath form (/html[1]/frameset[1]/frame[2]/html[1]/...).WaitForSelector:- A CSS selector is polled with the frame-aware
SelectorVisibleuntil it matches or the timeout ends, with the same error as before. - A selector with
>>hops, or an XPath, still goes to the runtime as written.
- A CSS selector is polled with the frame-aware
SelectorVisiblenow also matches inside open shadow roots. The runtime's wait pierced shadow roots, so moving CSS waits ontoSelectorVisiblekeeps that, andexpect/when {selector}now agree withwait.uploadwithoutintolists the file inputs of the page and its shown frames by deep XPath, refuses none or several as before, and gives the files to the one it finds.- The step reference (
skills/dagu/references/steptypes.md, regeneratedllms.txt) says which checks cover frames and shadow roots.
Tests
TestStagehandWaitsForSelectorInFramesuses the frameset fixture from #3429 (nested framesets, hidden frames), with an element added 2s after its frame loads. A wait finds the late element and a link in a nested frame, a>>hop selector and a deep XPath still resolve, and an element of a hidden frame times out with the usual error. The CSS cases failed before the fix with the runtime's timeout.TestStagehandPageChecks: an element inside an open shadow root is matched bySelectorVisibleand byWaitForSelector.TestStagehandUploadFindsTheFileInputInAFrame: on a frameset whose only file input is in a frame, an upload withoutintogoes straight to that input. Before the fix it failed with no file input. The existing upload tests, including the count of four file inputs on a page that has them, are unchanged.
Checked with the built binary against the live site: the wait above, which failed after 5s, now holds in 9 ms; the frame[name=mainfrm] >> frame >> … form holds as before.
Summary by cubic
Fixes wait: {selector} and upload without into so they find elements in the frames a page shows, not just its top document.
- A CSS selector
waitnow polls with the frame-aware visibility check until the element appears, with the same error as before;>>hops and XPath selectors still go to the runtime as written. - A selector wait's reads end with the wait's own timeout, so an unresponsive page now fails near the wait's deadline instead of a single page read's.
SelectorVisiblenow also matches inside open shadow roots, sowaitandexpect/when {selector}agree.uploadwithoutintofinds the page's only file input across shown frames by deep XPath, and still fails when there are none or several.- Checks read only frames of the page's own origin.
Tests
- Adds coverage for waits on late and nested-frame elements, hidden frames timing out, a wait near its own timeout on an unresponsive page, open shadow roots, and a file input in a frame.
Summary by CodeRabbit
- New Features
- Selector checks and waits can find elements in same-origin frames and open shadow roots, including nested frames and XPath selectors.
- Selector waits can detect elements that appear after the wait begins.
- Uploads without a specified selector can target the page’s sole file input, including one inside a visible frame.
- Documentation
- Updated browser-operation guidance to describe frame, shadow-root, upload, and selector-wait behavior.