feat(text): 'get text' (no selector) defaults to cross-frame whole-page read
So an agent never silently misses iframed content (listing descriptions etc.) without having to know the --all-frames flag. Single-frame pages are unchanged (identical to the old body read); multi-frame pages now include child frames — a strict superset. Skill + help updated to make the default and 'frames'/--main discoverable.
This commit is contained in:
+21
-15
@@ -2463,16 +2463,16 @@ fn parse_get(rest: &[&str], id: &str) -> Result<Value, ParseError> {
|
|||||||
if main {
|
if main {
|
||||||
return Ok(json!({ "id": id, "action": "gettext", "main": true }));
|
return Ok(json!({ "id": id, "action": "gettext", "main": true }));
|
||||||
}
|
}
|
||||||
// `get text` with no selector returns the whole page's text (body) —
|
// `get text` with no selector reads the WHOLE PAGE and now defaults
|
||||||
// a common convenience; previously it errored without a selector
|
// to cross-frame aggregation, so an agent gets a page's iframed
|
||||||
// (issue #24-D).
|
// content (listing descriptions etc.) without having to know about
|
||||||
let sel = rest
|
// `--all-frames` (#27). On a single-frame page this is identical to
|
||||||
.iter()
|
// the old body read; multi-frame pages get the child frames too —
|
||||||
.skip(1)
|
// a strict superset. An explicit selector stays element-scoped.
|
||||||
.find(|a| !a.starts_with("--"))
|
match rest.iter().skip(1).find(|a| !a.starts_with("--")).copied() {
|
||||||
.copied()
|
Some(sel) => Ok(json!({ "id": id, "action": "gettext", "selector": sel })),
|
||||||
.unwrap_or("body");
|
None => Ok(json!({ "id": id, "action": "gettext", "allFrames": true })),
|
||||||
Ok(json!({ "id": id, "action": "gettext", "selector": sel }))
|
}
|
||||||
}
|
}
|
||||||
Some("html") => {
|
Some("html") => {
|
||||||
let sel = rest.get(1).ok_or_else(|| ParseError::MissingArguments {
|
let sel = rest.get(1).ok_or_else(|| ParseError::MissingArguments {
|
||||||
@@ -4830,15 +4830,21 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_text_defaults_to_body() {
|
fn test_get_text_defaults_to_all_frames() {
|
||||||
// `get text` with no selector now returns the whole page (body) instead
|
// `get text` with no selector now reads the whole page across ALL frames
|
||||||
// of erroring (issue #24-D).
|
// by default (#27), so iframed content isn't silently missed. (Was: a
|
||||||
|
// top-frame `body` read, #24-D.)
|
||||||
let cmd = parse_command(&args("get text"), &default_flags()).unwrap();
|
let cmd = parse_command(&args("get text"), &default_flags()).unwrap();
|
||||||
assert_eq!(cmd["action"], "gettext");
|
assert_eq!(cmd["action"], "gettext");
|
||||||
assert_eq!(cmd["selector"], "body");
|
assert_eq!(cmd["allFrames"], true);
|
||||||
// An explicit selector still wins.
|
assert!(cmd.get("selector").is_none());
|
||||||
|
// An explicit selector still wins and stays element-scoped.
|
||||||
let cmd2 = parse_command(&args("get text h1"), &default_flags()).unwrap();
|
let cmd2 = parse_command(&args("get text h1"), &default_flags()).unwrap();
|
||||||
assert_eq!(cmd2["selector"], "h1");
|
assert_eq!(cmd2["selector"], "h1");
|
||||||
|
assert!(cmd2.get("allFrames").is_none());
|
||||||
|
// `text` top-level shortcut behaves the same.
|
||||||
|
let cmd3 = parse_command(&args("text"), &default_flags()).unwrap();
|
||||||
|
assert_eq!(cmd3["allFrames"], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
+4
-5
@@ -1959,8 +1959,7 @@ Usage: chrome-use get <subcommand> [args]
|
|||||||
Retrieves various types of information from elements or the page.
|
Retrieves various types of information from elements or the page.
|
||||||
|
|
||||||
Subcommands:
|
Subcommands:
|
||||||
text <selector> Get text content of element
|
text [selector] Element text; no selector = WHOLE PAGE, all frames
|
||||||
text --all-frames Aggregate text across ALL frames (incl. iframes)
|
|
||||||
text --main Main-content text only (skip nav/header/sidebar)
|
text --main Main-content text only (skip nav/header/sidebar)
|
||||||
html <selector> Get inner HTML of element
|
html <selector> Get inner HTML of element
|
||||||
value <selector> Get value of input element
|
value <selector> Get value of input element
|
||||||
@@ -1977,8 +1976,8 @@ Global Options:
|
|||||||
--session <name> Use specific session
|
--session <name> Use specific session
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
chrome-use get text @e1
|
chrome-use get text # whole page across ALL frames (default)
|
||||||
chrome-use get text --all-frames # read iframed content (listing pages)
|
chrome-use get text @e1 # one element
|
||||||
chrome-use get text --main # main content, no nav/sidebar boilerplate
|
chrome-use get text --main # main content, no nav/sidebar boilerplate
|
||||||
chrome-use frames # list frames + where the text lives
|
chrome-use frames # list frames + where the text lives
|
||||||
chrome-use get html "#content"
|
chrome-use get html "#content"
|
||||||
@@ -3190,7 +3189,7 @@ Navigation:
|
|||||||
|
|
||||||
Get Info: chrome-use get <what> [selector]
|
Get Info: chrome-use get <what> [selector]
|
||||||
text, html, value, attr <name>, title, url, count, box, styles, cdp-url
|
text, html, value, attr <name>, title, url, count, box, styles, cdp-url
|
||||||
text --all-frames (cross-frame), text --main (no boilerplate), frames (list)
|
text (no selector = whole page, all frames), text --main, frames (list)
|
||||||
|
|
||||||
Check State: chrome-use is <what> <selector>
|
Check State: chrome-use is <what> <selector>
|
||||||
visible, enabled, checked
|
visible, enabled, checked
|
||||||
|
|||||||
@@ -207,8 +207,8 @@ assigned fresh on every snapshot.
|
|||||||
For unstructured reading (no refs needed):
|
For unstructured reading (no refs needed):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
chrome-use get text @e1 # visible text of an element
|
chrome-use get text # WHOLE PAGE — all frames by default (see below)
|
||||||
chrome-use get text --all-frames # whole page, aggregated across ALL frames
|
chrome-use get text @e1 # visible text of one element (or a CSS selector)
|
||||||
chrome-use get text --main # main content only — skip nav/header/sidebar
|
chrome-use get text --main # main content only — skip nav/header/sidebar
|
||||||
chrome-use frames # list every frame + where the text lives
|
chrome-use frames # list every frame + where the text lives
|
||||||
chrome-use get html @e1 # innerHTML
|
chrome-use get html @e1 # innerHTML
|
||||||
@@ -219,13 +219,20 @@ chrome-use get url # current URL
|
|||||||
chrome-use get count ".item" # count matching elements
|
chrome-use get count ".item" # count matching elements
|
||||||
```
|
```
|
||||||
|
|
||||||
On listing/marketplace pages (Yahoo Auctions, Rakuten, Mercari shops) the seller's
|
**Whole-page text is cross-frame by default.** `chrome-use get text` with no
|
||||||
description often lives in a **child frame** or is buried under a "related items"
|
selector aggregates visible text across **every** frame — top document plus
|
||||||
sidebar, so a plain `get text body` returns only header/nav boilerplate. When the
|
same-process child frames plus cross-origin iframes — so you never silently miss
|
||||||
text you expect is missing: run `chrome-use frames` to see where it is, then
|
content that lives in an iframe (Yahoo Auctions / Rakuten / Mercari shop
|
||||||
`get text --all-frames` (reads every reachable frame incl. cross-origin iframes)
|
descriptions, embedded checkout/spec frames). Each child frame is delimited with
|
||||||
or `get text --main` (drops the global chrome). If the content is lazy-loaded,
|
a `----- frame [kind] url -----` marker. You do **not** need to remember a flag —
|
||||||
`scroll` it into view first.
|
the default already reads all frames. (`--all-frames` is still accepted as an
|
||||||
|
explicit alias.)
|
||||||
|
|
||||||
|
So: when text looks missing or wrong, you don't have to guess — just
|
||||||
|
`chrome-use get text` reads everything. To **see** the structure (which frame
|
||||||
|
holds what), run `chrome-use frames`. To **cut boilerplate** (global nav/header/
|
||||||
|
footer, "related items" sidebars), use `chrome-use get text --main`. If content
|
||||||
|
is lazy-loaded, `scroll` it into view first, then read.
|
||||||
|
|
||||||
## Interacting
|
## Interacting
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user