use blitz_dom::{Document, DocumentConfig};
use blitz_script::ScriptDocument;
use blitz_traits::events::{BlitzKeyEvent, KeyState, UiEvent};
use keyboard_types::{Code, Key, Location, Modifiers};
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.inner_mut().resolve(0.0);
doc.execute_scripts();
doc
}
fn text_of(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()
}
fn key(key: Key, state: KeyState) -> BlitzKeyEvent {
BlitzKeyEvent {
key: key.clone(),
code: match key {
Key::ArrowDown => Code::ArrowDown,
Key::ArrowUp => Code::ArrowUp,
_ => Code::Unidentified,
},
modifiers: Modifiers::empty(),
location: Location::Standard,
is_auto_repeating: false,
is_composing: false,
state,
text: None,
}
}
const PAGE: &str = r#"
<html><body>
<select id="country">
<option value="us">United States</option>
<option value="fr">France</option>
</select>
<div id="out"></div>
<script>
const out = document.getElementById("out");
const select = document.getElementById("country");
select.addEventListener("input", () => { out.textContent += "input|"; });
select.addEventListener("change", (event) => {
out.textContent += "change:" + event.target.value + "|";
});
</script>
</body></html>
"#;
fn press_arrow_down(doc: &mut ScriptDocument) {
let select = doc.inner().query_selector("#country").unwrap().unwrap();
doc.inner_mut().set_focus_to(select);
doc.handle_ui_event(UiEvent::KeyDown(key(Key::ArrowDown, KeyState::Pressed)));
doc.handle_ui_event(UiEvent::KeyUp(key(Key::ArrowDown, KeyState::Released)));
}
#[test]
fn a_keyboard_selection_fires_input_and_then_change() {
let mut doc = doc_from_html(PAGE);
press_arrow_down(&mut doc);
assert_eq!(
text_of(&doc, "#out"),
"input|change:fr|",
"a select commits on selection, so change must follow input immediately"
);
}
#[test]
fn a_keystroke_that_changes_nothing_fires_nothing() {
let mut doc = doc_from_html(PAGE);
press_arrow_down(&mut doc);
press_arrow_down(&mut doc);
assert_eq!(text_of(&doc, "#out"), "input|change:fr|");
}