webdriver_server/
script_argument_extraction.rs1use base::id::BrowsingContextId;
6use embedder_traits::WebDriverScriptCommand;
7use ipc_channel::ipc;
8use serde_json::Value;
9use webdriver::command::JavascriptCommandParameters;
10use webdriver::common::{ELEMENT_KEY, FRAME_KEY, SHADOW_KEY, WINDOW_KEY};
11use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult};
12
13use crate::{Handler, VerifyBrowsingContextIsOpen, wait_for_ipc_response_flatten};
14
15impl Handler {
16 pub(crate) fn extract_script_arguments(
18 &self,
19 parameters: JavascriptCommandParameters,
20 ) -> WebDriverResult<(String, Vec<String>)> {
21 let script = parameters.script;
24
25 let args: Vec<String> = parameters
29 .args
30 .as_deref()
31 .unwrap_or(&[])
32 .iter()
33 .map(|value| self.json_deserialize(value))
34 .collect::<WebDriverResult<Vec<_>>>()?;
35
36 Ok((script, args))
37 }
38
39 fn deserialize_web_element(&self, element: &Value) -> WebDriverResult<String> {
41 let element_ref = match element {
43 Value::String(string) => string.clone(),
44 _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, "")),
45 };
46
47 let (sender, receiver) = ipc::channel().unwrap();
49 self.browsing_context_script_command(
50 WebDriverScriptCommand::GetKnownElement(element_ref.clone(), sender),
51 VerifyBrowsingContextIsOpen::No,
52 )?;
53
54 wait_for_ipc_response_flatten(receiver)?;
55 Ok(format!("window.webdriverElement(\"{}\")", element_ref))
57 }
58
59 fn deserialize_shadow_root(&self, shadow_root: &Value) -> WebDriverResult<String> {
61 let shadow_root_ref = match shadow_root {
63 Value::String(string) => string.clone(),
64 _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, "")),
65 };
66
67 let (sender, receiver) = ipc::channel().unwrap();
69 self.browsing_context_script_command(
70 WebDriverScriptCommand::GetKnownShadowRoot(shadow_root_ref.clone(), sender),
71 VerifyBrowsingContextIsOpen::No,
72 )?;
73
74 wait_for_ipc_response_flatten(receiver)?;
75 Ok(format!(
77 "window.webdriverShadowRoot(\"{}\")",
78 shadow_root_ref
79 ))
80 }
81
82 fn deserialize_web_frame(&self, frame: &Value) -> WebDriverResult<String> {
84 let frame_ref = match frame {
86 Value::String(string) => string.clone(),
87 _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, "")),
88 };
89
90 let Some(browsing_context_id) = BrowsingContextId::from_string(&frame_ref) else {
93 return Err(WebDriverError::new(ErrorStatus::NoSuchFrame, ""));
96 };
97
98 match self.verify_browsing_context_is_open(browsing_context_id) {
99 Ok(_) => Ok(format!("window.webdriverFrame(\"{frame_ref}\")")),
101 Err(_) => Err(WebDriverError::new(ErrorStatus::NoSuchFrame, "")),
103 }
104 }
105
106 fn deserialize_web_window(&self, window: &Value) -> WebDriverResult<String> {
108 let window_ref = match window {
110 Value::String(string) => string.clone(),
111 _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, "")),
112 };
113
114 let (sender, receiver) = ipc::channel().unwrap();
117 self.browsing_context_script_command(
118 WebDriverScriptCommand::GetKnownWindow(window_ref.clone(), sender),
119 VerifyBrowsingContextIsOpen::No,
120 )?;
121
122 wait_for_ipc_response_flatten(receiver)?;
125 Ok(format!("window.webdriverWindow(\"{window_ref}\")"))
127 }
128
129 fn json_deserialize(&self, v: &Value) -> WebDriverResult<String> {
131 let res = match v {
132 Value::Array(list) => {
133 let elems = list
134 .iter()
135 .map(|v| self.json_deserialize(v))
136 .collect::<WebDriverResult<Vec<_>>>()?;
137 format!("[{}]", elems.join(", "))
138 },
139 Value::Object(map) => {
140 if let Some(id) = map.get(ELEMENT_KEY) {
141 return self.deserialize_web_element(id);
142 }
143 if let Some(id) = map.get(SHADOW_KEY) {
144 return self.deserialize_shadow_root(id);
145 }
146 if let Some(id) = map.get(FRAME_KEY) {
147 return self.deserialize_web_frame(id);
148 }
149 if let Some(id) = map.get(WINDOW_KEY) {
150 return self.deserialize_web_window(id);
151 }
152 let elems = map
153 .iter()
154 .map(|(k, v)| {
155 let key = serde_json::to_string(k)?;
156 let arg = self.json_deserialize(v)?;
157 Ok(format!("{key}: {arg}"))
158 })
159 .collect::<WebDriverResult<Vec<String>>>()?;
160 format!("{{{}}}", elems.join(", "))
161 },
162 _ => serde_json::to_string(v)?,
163 };
164
165 Ok(res)
166 }
167}