use super::support::{MockRdpServer, load_fixture};
fn ff_rdp_bin() -> std::path::PathBuf {
std::path::PathBuf::from(env!("CARGO_BIN_EXE_ff-rdp"))
}
fn base_args(port: u16) -> Vec<String> {
vec![
"--host".to_owned(),
"127.0.0.1".to_owned(),
"--port".to_owned(),
port.to_string(),
"--no-daemon".to_owned(),
]
}
fn dom_tree_server() -> MockRdpServer {
MockRdpServer::new()
.on("listTabs", load_fixture("list_tabs_response.json"))
.on("getTarget", load_fixture("get_target_response.json"))
.on(
"getWalker",
load_fixture("inspector_get_walker_response.json"),
)
.on(
"documentElement",
load_fixture("dom_walker_document_element_response.json"),
)
.on(
"querySelector",
load_fixture("dom_walker_query_selector_response.json"),
)
.on(
"children",
load_fixture("dom_walker_children_response.json"),
)
}
#[test]
fn dom_tree_outputs_json() {
let server = dom_tree_server();
let port = server.port();
let handle = std::thread::spawn(move || server.serve_one());
let mut args = base_args(port);
args.extend(["dom".to_owned(), "tree".to_owned()]);
let output = std::process::Command::new(ff_rdp_bin())
.args(&args)
.output()
.expect("failed to spawn ff-rdp");
handle.join().unwrap();
assert!(
output.status.success(),
"expected success, stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let json: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("stdout must be valid JSON");
let results = &json["results"];
assert_eq!(
results["nodeType"], 1,
"root node should be an element (nodeType 1)"
);
assert_eq!(
results["nodeName"], "HTML",
"root should be the HTML element"
);
let children = results["children"]
.as_array()
.expect("results should have a children array");
assert!(!children.is_empty(), "HTML should have child nodes");
let names: Vec<&str> = children
.iter()
.filter_map(|c| c["nodeName"].as_str())
.collect();
assert!(names.contains(&"HEAD"), "children should include HEAD");
assert!(names.contains(&"BODY"), "children should include BODY");
assert_eq!(json["total"], 1);
}
#[test]
fn dom_tree_with_selector() {
let server = dom_tree_server();
let port = server.port();
let handle = std::thread::spawn(move || server.serve_one());
let mut args = base_args(port);
args.extend(["dom".to_owned(), "tree".to_owned(), "h1".to_owned()]);
let output = std::process::Command::new(ff_rdp_bin())
.args(&args)
.output()
.expect("failed to spawn ff-rdp");
handle.join().unwrap();
assert!(
output.status.success(),
"expected success, stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let json: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("stdout must be valid JSON");
let results = &json["results"];
assert_eq!(
results["nodeName"], "H1",
"with selector h1, result should be H1 element"
);
assert_eq!(
results["nodeType"], 1,
"H1 should be an element node (nodeType 1)"
);
assert_eq!(
json["meta"]["selector"], "h1",
"meta should record the selector"
);
}
#[test]
fn dom_tree_strips_actor_ids() {
let server = dom_tree_server();
let port = server.port();
let handle = std::thread::spawn(move || server.serve_one());
let mut args = base_args(port);
args.extend(["dom".to_owned(), "tree".to_owned()]);
let output = std::process::Command::new(ff_rdp_bin())
.args(&args)
.output()
.expect("failed to spawn ff-rdp");
handle.join().unwrap();
assert!(
output.status.success(),
"expected success, stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let json: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("stdout must be valid JSON");
assert!(
json["results"].get("actor").is_none(),
"actor ID should be stripped from root node"
);
if let Some(children) = json["results"]["children"].as_array() {
for child in children {
assert!(
child.get("actor").is_none(),
"actor ID should be stripped from child node"
);
}
}
}
#[test]
fn dom_tree_with_jq_filter() {
let server = dom_tree_server();
let port = server.port();
let handle = std::thread::spawn(move || server.serve_one());
let mut args = base_args(port);
args.extend([
"--jq".to_owned(),
".results.nodeName".to_owned(),
"dom".to_owned(),
"tree".to_owned(),
]);
let output = std::process::Command::new(ff_rdp_bin())
.args(&args)
.output()
.expect("failed to spawn ff-rdp");
handle.join().unwrap();
assert!(
output.status.success(),
"expected success, stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert_eq!(
stdout.trim(),
"\"HTML\"",
"jq should extract the root nodeName"
);
}