#[cfg(test)]
mod tests {
use crate::dom::views::{EnhancedDOMTreeNode, NodeType, PageIntent, SemanticRole};
use crate::perception::PerceptionEngine;
use std::collections::HashMap;
fn make_node(tag: &str, text: &str) -> EnhancedDOMTreeNode {
let mut node = EnhancedDOMTreeNode::new(
1,
1,
NodeType::ElementNode,
tag.to_string(),
text.to_string(),
"target-1".to_string(),
);
node.children_nodes = Some(vec![]);
node
}
fn make_node_with_attrs(tag: &str, attrs: HashMap<String, String>) -> EnhancedDOMTreeNode {
let mut node = EnhancedDOMTreeNode::new(
1,
1,
NodeType::ElementNode,
tag.to_string(),
"".to_string(),
"target-1".to_string(),
);
node.attributes = attrs;
node.children_nodes = Some(vec![]);
node
}
fn add_child(parent: &mut EnhancedDOMTreeNode, child: EnhancedDOMTreeNode) {
if let Some(ref mut children) = parent.children_nodes {
children.push(child);
}
}
#[test]
fn test_detect_login_form() {
let mut root = make_node("form", "");
let password = make_node_with_attrs("input", {
let mut m = HashMap::new();
m.insert("type".to_string(), "password".to_string());
m
});
add_child(&mut root, password);
let engine = PerceptionEngine::new();
let (intent, _) = engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::LoginForm));
assert_eq!(intent, Some(PageIntent::Login));
}
#[test]
fn test_detect_search_form() {
let mut root = make_node("form", "");
let search_btn = make_node_with_attrs("button", {
let mut m = HashMap::new();
m.insert("value".to_string(), "Search".to_string());
m
});
add_child(&mut root, search_btn);
let engine = PerceptionEngine::new();
let (_intent, _) = engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::SearchForm));
}
#[test]
fn test_detect_captcha() {
let mut root = make_node("div", "Please complete the CAPTCHA");
let engine = PerceptionEngine::new();
let (intent, _) = engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::Captcha));
assert_eq!(intent, Some(PageIntent::Captcha));
}
#[test]
fn test_detect_cookie_consent() {
let mut root = make_node("div", "We use cookies. Accept?");
let mut attrs = HashMap::new();
attrs.insert("class".to_string(), "cookie-banner".to_string());
root.attributes = attrs;
let engine = PerceptionEngine::new();
let (intent, _) = engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::CookieConsent));
assert_eq!(intent, Some(PageIntent::CookieConsent));
}
#[test]
fn test_detect_article() {
let mut root = make_node("article", "");
let engine = PerceptionEngine::new();
let (intent, _) = engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::Article));
assert_eq!(intent, Some(PageIntent::Article));
}
#[test]
fn test_detect_navigation() {
let mut root = make_node("nav", "");
let engine = PerceptionEngine::new();
engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::Navigation));
}
#[test]
fn test_detect_submit_button() {
let mut root = make_node("button", "Submit");
let engine = PerceptionEngine::new();
engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::SubmitButton));
}
#[test]
fn test_detect_pagination() {
let mut root = make_node("a", "Next »");
let engine = PerceptionEngine::new();
engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::Pagination));
}
#[test]
fn test_detect_text_input() {
let mut root = make_node_with_attrs("input", {
let mut m = HashMap::new();
m.insert("type".to_string(), "text".to_string());
m.insert("placeholder".to_string(), "Enter your name".to_string());
m
});
let engine = PerceptionEngine::new();
engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::TextInput));
}
#[test]
fn test_detect_dropdown() {
let mut root = make_node("select", "");
let engine = PerceptionEngine::new();
engine.perceive(&mut root);
assert_eq!(root.semantic_role, Some(SemanticRole::Dropdown));
}
#[test]
fn test_structural_elements() {
let mut header = make_node("header", "");
let mut footer = make_node("footer", "");
let mut aside = make_node("aside", "");
let mut main = make_node("main", "");
let engine = PerceptionEngine::new();
engine.perceive(&mut header);
engine.perceive(&mut footer);
engine.perceive(&mut aside);
engine.perceive(&mut main);
assert_eq!(header.semantic_role, Some(SemanticRole::Header));
assert_eq!(footer.semantic_role, Some(SemanticRole::Footer));
assert_eq!(aside.semantic_role, Some(SemanticRole::Sidebar));
assert_eq!(main.semantic_role, Some(SemanticRole::MainContent));
}
#[test]
fn test_non_element_nodes_unchanged() {
let mut text_node = EnhancedDOMTreeNode::new(
1,
1,
NodeType::TextNode,
"#text".to_string(),
"Hello world".to_string(),
"target-1".to_string(),
);
let engine = PerceptionEngine::new();
engine.perceive(&mut text_node);
assert_eq!(text_node.semantic_role, None);
assert_eq!(text_node.semantic_confidence, 0.0);
}
#[test]
fn test_perception_config_disabled() {
let mut root = make_node("form", "");
let password = make_node_with_attrs("input", {
let mut m = HashMap::new();
m.insert("type".to_string(), "password".to_string());
m
});
add_child(&mut root, password);
let config = crate::perception::PerceptionConfig {
enable_role_inference: false,
enable_page_intent: false,
..Default::default()
};
let engine = PerceptionEngine::with_config(config);
let (intent, _) = engine.perceive(&mut root);
assert_eq!(root.semantic_role, None);
assert_eq!(intent, None);
}
#[test]
fn test_page_intent_confidence_normalization() {
let mut root = make_node("form", "");
let password = make_node_with_attrs("input", {
let mut m = HashMap::new();
m.insert("type".to_string(), "password".to_string());
m
});
add_child(&mut root, password);
let engine = PerceptionEngine::new();
let (_, confidence) = engine.perceive(&mut root);
assert!(confidence > 0.0 && confidence <= 0.99, "confidence was {confidence}");
}
}