diff options
-rw-r--r-- | components/script/script_thread.rs | 8 | ||||
-rw-r--r-- | components/script/webdriver_handlers.rs | 21 | ||||
-rw-r--r-- | components/shared/embedder/webdriver.rs | 1 | ||||
-rw-r--r-- | components/webdriver_server/lib.rs | 23 |
4 files changed, 53 insertions, 0 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index e7f60e23772..1260fa9867a 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2280,6 +2280,14 @@ impl ScriptThread { can_gc, ) }, + WebDriverScriptCommand::GetElementShadowRoot(element_id, reply) => { + webdriver_handlers::handle_get_element_shadow_root( + &documents, + pipeline_id, + element_id, + reply, + ) + }, WebDriverScriptCommand::ElementClick(element_id, reply) => { webdriver_handlers::handle_element_click( &documents, diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index c81dcbd85fd..322839aa078 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -843,6 +843,27 @@ pub(crate) fn handle_find_element_elements_tag_name( .unwrap(); } +/// <https://www.w3.org/TR/webdriver2/#dfn-get-element-shadow-root> +pub(crate) fn handle_get_element_shadow_root( + documents: &DocumentCollection, + pipeline: PipelineId, + element_id: String, + reply: IpcSender<Result<Option<String>, ErrorStatus>>, +) { + reply + .send( + find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| match node + .downcast::<Element>( + ) { + Some(element) => Ok(element + .GetShadowRoot() + .map(|x| x.upcast::<Node>().unique_id(pipeline))), + None => Err(ErrorStatus::NoSuchElement), + }), + ) + .unwrap(); +} + pub(crate) fn handle_will_send_keys( documents: &DocumentCollection, pipeline: PipelineId, diff --git a/components/shared/embedder/webdriver.rs b/components/shared/embedder/webdriver.rs index ad1271a045c..d28bb6fc6c3 100644 --- a/components/shared/embedder/webdriver.rs +++ b/components/shared/embedder/webdriver.rs @@ -130,6 +130,7 @@ pub enum WebDriverScriptCommand { IpcSender<Result<Vec<String>, ErrorStatus>>, ), FindElementElementsTagName(String, String, IpcSender<Result<Vec<String>, ErrorStatus>>), + GetElementShadowRoot(String, IpcSender<Result<Option<String>, ErrorStatus>>), ElementClick(String, IpcSender<Result<Option<String>, ErrorStatus>>), GetActiveElement(IpcSender<Option<String>>), GetComputedRole(String, IpcSender<Result<Option<String>, ErrorStatus>>), diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 1b585319703..5d5159f7232 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -1214,6 +1214,28 @@ impl Handler { } } + fn handle_get_shadow_root(&self, element: WebElement) -> WebDriverResult<WebDriverResponse> { + let (sender, receiver) = ipc::channel().unwrap(); + let cmd = WebDriverScriptCommand::GetElementShadowRoot(element.to_string(), sender); + self.browsing_context_script_command(cmd)?; + match wait_for_script_response(receiver)? { + Ok(value) => { + if value.is_none() { + return Err(WebDriverError::new( + ErrorStatus::NoSuchShadowRoot, + "No shadow root found for the element", + )); + } + let value_resp = serde_json::to_value( + value.map(|x| serde_json::to_value(WebElement(x)).unwrap()), + )?; + let shadow_root_value = json!({ SHADOW_ROOT_IDENTIFIER: value_resp }); + Ok(WebDriverResponse::Generic(ValueResponse(shadow_root_value))) + }, + Err(error) => Err(WebDriverError::new(error, "")), + } + } + // https://w3c.github.io/webdriver/webdriver-spec.html#get-element-rect fn handle_element_rect(&self, element: &WebElement) -> WebDriverResult<WebDriverResponse> { let (sender, receiver) = ipc::channel().unwrap(); @@ -1936,6 +1958,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler { WebDriverCommand::FindElementElements(ref element, ref parameters) => { self.handle_find_elements_from_element(element, parameters) }, + WebDriverCommand::GetShadowRoot(element) => self.handle_get_shadow_root(element), WebDriverCommand::GetNamedCookie(name) => self.handle_get_cookie(name), WebDriverCommand::GetCookies => self.handle_get_cookies(), WebDriverCommand::GetActiveElement => self.handle_active_element(), |