testing_library_dom/queries/
display_value.rs1use wasm_bindgen::JsCast;
2use web_sys::{HtmlElement, HtmlInputElement, HtmlOptionElement, HtmlSelectElement};
3
4use crate::{
5 build_queries,
6 error::QueryError,
7 get_node_text::get_node_text,
8 matches::{fuzzy_matches, make_normalizer, matches},
9 types::{Matcher, MatcherOptions, NormalizerOptions},
10 util::{html_collection_to_vec, node_list_to_vec},
11};
12
13pub fn _query_all_by_display_value<M: Into<Matcher>>(
14 container: &HtmlElement,
15 value: M,
16 options: MatcherOptions,
17) -> Result<Vec<HtmlElement>, QueryError> {
18 let value = value.into();
19 let matcher = match options.exact.unwrap_or(true) {
20 true => matches,
21 false => fuzzy_matches,
22 };
23 let match_normalizer = make_normalizer(NormalizerOptions {
24 trim: options.trim,
25 collapse_whitespace: options.collapse_whitespace,
26 normalizer: options.normalizer,
27 })?;
28
29 Ok(node_list_to_vec::<HtmlElement>(
30 container
31 .query_selector_all("input,textarea,select")
32 .map_err(QueryError::JsError)?,
33 )
34 .into_iter()
35 .filter(|node| {
36 if node.tag_name() == "SELECT" {
37 html_collection_to_vec::<HtmlOptionElement>(
38 node.unchecked_ref::<HtmlSelectElement>().options().into(),
39 )
40 .into_iter()
41 .filter(|option| option.selected())
42 .any(|option_node| {
43 matcher(
44 Some(get_node_text(&option_node)),
45 Some(&option_node),
46 &value,
47 match_normalizer.as_ref(),
48 )
49 })
50 } else {
51 matcher(
52 Some(node.unchecked_ref::<HtmlInputElement>().value()),
53 Some(node),
54 &value,
55 match_normalizer.as_ref(),
56 )
57 }
58 })
59 .collect())
60}
61
62fn get_multiple_error(
63 _container: &HtmlElement,
64 value: Matcher,
65 _options: MatcherOptions,
66) -> Result<String, QueryError> {
67 Ok(format!(
68 "Found multiple elements with the display value: {value}"
69 ))
70}
71
72fn get_missing_error(
73 _container: &HtmlElement,
74 value: Matcher,
75 _options: MatcherOptions,
76) -> Result<String, QueryError> {
77 Ok(format!(
78 "Unable to find an element with the display value: {value}"
79 ))
80}
81
82build_queries!(
83 _query_all_by_display_value,
84 get_multiple_error,
85 get_missing_error,
86 display_value,
87 crate::types::Matcher,
88 crate::types::MatcherOptions
89);
90
91pub use internal::{
92 find_all_by_display_value, find_by_display_value, get_all_by_display_value,
93 get_by_display_value, query_all_by_display_value, query_by_display_value,
94};