Read the frames a page shows in fixed checks
Summary
On a public bid-information site built of framesets, fixed page checks never held. In a browser session on its search page:
{"expect": {"text": "農業大学校"}} -> expect failed: expectation not met: the page text does not contain "農業大学校" (after 120 s)
{"expect": {"selector": "a"}} -> expect failed: expectation not met: "a" is not visible (after 120 s)
Both texts and links were on screen, in frames.
Root cause
PageText read document.body.innerText and SelectorVisible ran document.querySelectorAll in the top document only. On a frameset page document.body is the <frameset> element, which has no text, and every element a person sees lives in a frame's document. So expect/when with {text} or {selector} could never hold, an expect waited out its whole window, and a sign-in guarded by when: {selector: "form#login"} on such a site was always skipped.
The model-backed reads (act, extract, statement checks, the session outline) already cover frames through the runtime's snapshot; only these two fixed checks did not.
Fix
Both expressions now go through shownDocuments, which returns the top document and the documents of the frames and iframes it shows, nested ones too:
PageTextjoins theinnerTextof each.SelectorVisiblematches the selector in each, with the element's own window computing its style.
A frame with no box (hidden, or collapsed to zero size) is left out, as a hidden element's text is. A cross-site frame has no readable contentDocument and is left out as before.
Tests
TestStagehandPageChecksReadFrames serves a frameset whose content frame is a nested frameset, plus a menu frame holding a hidden iframe, and asserts that PageText holds text from the menu frame and from the nested frame but not from the hidden one, and that SelectorVisible finds a link in the nested frame but not an element in the hidden one. Before the fix PageText returned "" and SelectorVisible("#show") was false.
Checked with the built binary: on a local frameset fixture and on the live site, expect {text} and expect {selector} that failed after their full window now hold at once.
Summary by cubic
Fixed expect/when checks so text and selector checks read the frames a page shows, not just the top document. On frameset-based sites, the top document is a <frameset> with no text, so {text} and {selector} checks never held even when the content was on screen.
- Page text now joins the text of the page's document and the documents of the frames and iframes it shows, nested ones too.
- Selector visibility now matches the selector in each shown document, using the element's own window for style computation.
- Frames hidden by display or visibility, and bodies that are not rendered, are left out; cross-site frames stay unreadable as before.
- Added
TestStagehandPageChecksReadFrames, which verifies text and selectors from nested frames are found and hidden frames and bodies are not.
Summary by CodeRabbit
- New Features
- Page text now includes content from visible frames, including nested frames, while excluding hidden frames and frames that cannot be accessed.
- Visibility checks now recognize visible elements inside frames and distinguish them from elements in hidden frames.