use blitz_dom::{Document, DocumentConfig};
use blitz_script::ScriptDocument;
use blitz_traits::events::{DomEvent, DomEventData};
fn doc_from_html(html: &str) -> ScriptDocument {
let mut doc = ScriptDocument::from_html(
html,
DocumentConfig {
viewport: Some(blitz_traits::shell::Viewport::new(
800,
600,
1.0,
blitz_traits::shell::ColorScheme::Light,
)),
..Default::default()
},
);
doc.execute_scripts();
doc
}
fn text_of_selector(doc: &ScriptDocument, selector: &str) -> String {
let inner = doc.inner();
let node_id = inner
.query_selector(selector)
.unwrap()
.unwrap_or_else(|| panic!("no node matching {selector}"));
inner.get_node(node_id).unwrap().text_content()
}
#[test]
fn scroll_into_view_is_callable_from_page_script() {
let mut doc = doc_from_html(
r#"
<html><body style="margin:0">
<div id="pane" style="height:100px; overflow:scroll">
<div style="height:400px"></div>
<div id="target" style="height:20px">target</div>
</div>
<button id="jump">jump</button>
<div id="out"></div>
<script>
const out = document.getElementById("out");
document.getElementById("jump").addEventListener("click", () => {
try {
document.getElementById("target").scrollIntoView({ behavior: "instant" });
out.textContent = "called";
} catch (error) {
out.textContent = "threw:" + error;
}
});
</script>
</body></html>
"#,
);
doc.inner_mut().resolve(0.0);
let (jump, pointer) = {
let inner = doc.inner();
let jump = inner.query_selector("#jump").unwrap().unwrap();
let pointer = match inner
.get_node(jump)
.unwrap()
.synthetic_click_event(keyboard_types::Modifiers::empty())
{
DomEventData::Click(pointer) => pointer,
_ => unreachable!(),
};
(jump, pointer)
};
doc.dispatch_dom_event(DomEvent::new(jump, DomEventData::Click(pointer)));
assert_eq!(text_of_selector(&doc, "#out"), "called");
let scrolled = {
let inner = doc.inner();
let pane = inner.query_selector("#pane").unwrap().unwrap();
inner.get_node(pane).unwrap().scroll_offset().y
};
assert!(
scrolled > 0.0,
"scrollIntoView must move the nearest scroll container, not just return"
);
}