testing_library_dom/
pretty_dom.rs1use std::rc::Rc;
2
3use pretty_format::PrettyFormatOptions;
4use wasm_bindgen::{JsCast, JsValue};
5use web_sys::{Document, Element, Node};
6
7use crate::{config::get_config, dom_element_filter::DomElementFilter, helpers::get_document};
8
9pub enum DocumentOrElement {
10 Document(Document),
11 Element(Element),
12}
13
14impl From<Document> for DocumentOrElement {
15 fn from(value: Document) -> Self {
16 Self::Document(value)
17 }
18}
19
20impl From<Element> for DocumentOrElement {
21 fn from(value: Element) -> Self {
22 Self::Element(value)
23 }
24}
25
26fn should_highlight() -> bool {
27 false
31}
32
33fn filter_comments_and_default_ignore_tags_tags(node: &Node) -> bool {
34 node.node_type() != Node::COMMENT_NODE
35 && (node.node_type() != Node::ELEMENT_NODE
36 || !node
37 .unchecked_ref::<Element>()
38 .matches(&get_config().default_ignore)
39 .unwrap_or(false))
40}
41
42pub fn pretty_dom(dom: Option<DocumentOrElement>, max_length: Option<usize>) -> String {
43 let dom = dom.unwrap_or_else(|| {
44 get_document()
45 .body()
46 .expect("Body should exist.")
47 .unchecked_into::<Element>()
48 .into()
49 });
50 let max_length = max_length.unwrap_or(7000);
51
52 if max_length == 0 {
53 return "".into();
54 }
55
56 let dom: JsValue = match dom {
57 DocumentOrElement::Document(document) => match document.document_element() {
58 Some(element) => element.unchecked_into(),
59 None => document.unchecked_into(),
60 },
61 DocumentOrElement::Element(element) => element.unchecked_into(),
62 };
63
64 let filter_node = filter_comments_and_default_ignore_tags_tags;
66
67 let debug_content = pretty_format::format(
68 &dom,
69 PrettyFormatOptions::default()
71 .plugins(vec![Rc::new(DomElementFilter::new(Box::new(filter_node)))])
72 .print_function_name(false)
73 .highlight(should_highlight()),
74 )
75 .expect("TODO: return result from pretty_dom()");
76
77 if debug_content.len() > max_length {
78 format!("{}...", &debug_content[0..max_length])
79 } else {
80 debug_content
81 }
82}