diff options
-rw-r--r-- | components/script/dom/bindings/conversions.rs | 17 | ||||
-rw-r--r-- | components/script/script_thread.rs | 9 | ||||
-rw-r--r-- | components/script/webdriver_handlers.rs | 41 | ||||
-rw-r--r-- | components/script_traits/webdriver_msg.rs | 3 | ||||
-rw-r--r-- | components/webdriver_server/lib.rs | 26 | ||||
-rw-r--r-- | tests/wpt/metadata/webdriver/tests/element_send_keys/interactability.py.ini | 9 | ||||
-rw-r--r-- | tests/wpt/metadata/webdriver/tests/get_element_property/get.py.ini | 31 | ||||
-rw-r--r-- | tests/wpt/metadata/webdriver/tests/refresh/refresh.py.ini | 6 |
8 files changed, 119 insertions, 23 deletions
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 17f72956ca1..c84adf64dbb 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -60,7 +60,7 @@ use js::jsapi::{ }; use js::jsapi::{JS_NewStringCopyN, JS_StringHasLatin1Chars}; use js::jsval::{ObjectValue, StringValue, UndefinedValue}; -use js::rust::wrappers::{JS_GetProperty, JS_IsArrayObject}; +use js::rust::wrappers::{JS_GetProperty, JS_HasProperty, JS_IsArrayObject}; use js::rust::{get_object_class, is_dom_class, is_dom_object, maybe_wrap_value, ToString}; use js::rust::{HandleId, HandleObject, HandleValue, MutableHandleValue}; use num_traits::Float; @@ -596,11 +596,18 @@ pub unsafe fn get_property_jsval( Ok(cname) => cname, Err(_) => return Ok(()), }; - JS_GetProperty(cx, object, cname.as_ptr(), rval); - if JS_IsExceptionPending(cx) { - return Err(Error::JSFailed); + let mut found = false; + if JS_HasProperty(cx, object, cname.as_ptr(), &mut found) && found { + JS_GetProperty(cx, object, cname.as_ptr(), rval); + if JS_IsExceptionPending(cx) { + return Err(Error::JSFailed); + } + Ok(()) + } else if JS_IsExceptionPending(cx) { + Err(Error::JSFailed) + } else { + Ok(()) } - Ok(()) } /// Get a property from a JS object, and convert it to a Rust value. diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 8193c9b7ace..0ceed35db57 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2157,6 +2157,15 @@ impl ScriptThread { reply, ) }, + WebDriverScriptCommand::GetElementProperty(node_id, name, reply) => { + webdriver_handlers::handle_get_property( + &*documents, + pipeline_id, + node_id, + name, + reply, + ) + }, WebDriverScriptCommand::GetElementCSS(node_id, name, reply) => { webdriver_handlers::handle_get_css(&*documents, pipeline_id, node_id, name, reply) }, diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index 3871b7a6ef5..ab08c0efe7d 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -12,9 +12,11 @@ use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use crate::dom::bindings::codegen::Bindings::XMLSerializerBinding::XMLSerializerMethods; use crate::dom::bindings::conversions::{ - ConversionResult, FromJSValConvertible, StringificationBehavior, + get_property_jsval, ConversionResult, FromJSValConvertible, StringificationBehavior, }; +use crate::dom::bindings::error::throw_dom_exception; use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::element::Element; @@ -710,6 +712,43 @@ pub fn handle_get_attribute( .unwrap(); } +#[allow(unsafe_code)] +pub fn handle_get_property( + documents: &Documents, + pipeline: PipelineId, + node_id: String, + name: String, + reply: IpcSender<Result<WebDriverJSValue, ()>>, +) { + reply + .send(match find_node_by_unique_id(documents, pipeline, node_id) { + Some(node) => { + let cx = documents.find_document(pipeline).unwrap().window().get_cx(); + + rooted!(in(cx) let mut property = UndefinedValue()); + match unsafe { + get_property_jsval( + cx, + node.reflector().get_jsobject(), + &name, + property.handle_mut(), + ) + } { + Ok(_) => match unsafe { jsval_to_webdriver(cx, property.handle()) } { + Ok(property) => Ok(property), + Err(_) => Ok(WebDriverJSValue::Undefined), + }, + Err(error) => { + unsafe { throw_dom_exception(cx, &node.reflector().global(), error) }; + Ok(WebDriverJSValue::Undefined) + }, + } + }, + None => Err(()), + }) + .unwrap(); +} + pub fn handle_get_css( documents: &Documents, pipeline: PipelineId, diff --git a/components/script_traits/webdriver_msg.rs b/components/script_traits/webdriver_msg.rs index 2d15172fe30..7849a8580ef 100644 --- a/components/script_traits/webdriver_msg.rs +++ b/components/script_traits/webdriver_msg.rs @@ -41,6 +41,7 @@ pub enum WebDriverScriptCommand { GetCookie(String, IpcSender<Vec<Serde<Cookie<'static>>>>), GetCookies(IpcSender<Vec<Serde<Cookie<'static>>>>), GetElementAttribute(String, String, IpcSender<Result<Option<String>, ()>>), + GetElementProperty(String, String, IpcSender<Result<WebDriverJSValue, ()>>), GetElementCSS(String, String, IpcSender<Result<String, ()>>), GetElementRect(String, IpcSender<Result<Rect<f64>, ()>>), GetElementTagName(String, IpcSender<Result<String, ()>>), @@ -59,7 +60,7 @@ pub enum WebDriverCookieError { UnableToSetCookie, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum WebDriverJSValue { Undefined, Null, diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index dd745ae256d..d06ffb3a8fc 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -211,6 +211,7 @@ impl WebDriverExtensionCommand for ServoExtensionCommand { } } +#[derive(Clone)] struct SendableWebDriverJSValue(pub WebDriverJSValue); impl Serialize for SendableWebDriverJSValue { @@ -1163,6 +1164,28 @@ impl Handler { } } + fn handle_element_property( + &self, + element: &WebElement, + name: &str, + ) -> WebDriverResult<WebDriverResponse> { + let (sender, receiver) = ipc::channel().unwrap(); + + let cmd = + WebDriverScriptCommand::GetElementProperty(element.id.clone(), name.to_owned(), sender); + self.browsing_context_script_command(cmd)?; + + match receiver.recv().unwrap() { + Ok(value) => Ok(WebDriverResponse::Generic(ValueResponse( + serde_json::to_value(SendableWebDriverJSValue(value))?, + ))), + Err(_) => Err(WebDriverError::new( + ErrorStatus::StaleElementReference, + "Unable to find element in document", + )), + } + } + fn handle_element_css( &self, element: &WebElement, @@ -1586,6 +1609,9 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler { WebDriverCommand::GetElementAttribute(ref element, ref name) => { self.handle_element_attribute(element, name) }, + WebDriverCommand::GetElementProperty(ref element, ref name) => { + self.handle_element_property(element, name) + }, WebDriverCommand::GetCSSValue(ref element, ref name) => { self.handle_element_css(element, name) }, diff --git a/tests/wpt/metadata/webdriver/tests/element_send_keys/interactability.py.ini b/tests/wpt/metadata/webdriver/tests/element_send_keys/interactability.py.ini index 5432914e217..b068acec62e 100644 --- a/tests/wpt/metadata/webdriver/tests/element_send_keys/interactability.py.ini +++ b/tests/wpt/metadata/webdriver/tests/element_send_keys/interactability.py.ini @@ -8,24 +8,15 @@ [test_visibility_hidden] expected: FAIL - [test_transparent_element] - expected: FAIL - [test_iframe_is_interactable] expected: FAIL [test_readonly_element] expected: FAIL - [test_obscured_element] - expected: FAIL - [test_document_element_is_interactable] expected: FAIL - [test_body_is_interactable] - expected: FAIL - [test_hidden] expected: FAIL diff --git a/tests/wpt/metadata/webdriver/tests/get_element_property/get.py.ini b/tests/wpt/metadata/webdriver/tests/get_element_property/get.py.ini index ede060751a2..1e970ff340b 100644 --- a/tests/wpt/metadata/webdriver/tests/get_element_property/get.py.ini +++ b/tests/wpt/metadata/webdriver/tests/get_element_property/get.py.ini @@ -1,2 +1,31 @@ [get.py] - disabled: Unimplemented WebDriver command + [test_primitives[js_primitive3-py_primitive3\]] + expected: FAIL + + [test_idl_attribute] + expected: FAIL + + [test_element_not_found] + expected: FAIL + + [test_primitives_set_by_execute_script[42-42\]] + expected: FAIL + + [test_primitives[js_primitive2-py_primitive2\]] + expected: FAIL + + [test_primitives_set_by_execute_script[js_primitive2-py_primitive2\]] + expected: FAIL + + [test_mutated_element] + expected: FAIL + + [test_no_browsing_context] + expected: ERROR + + [test_primitives_set_by_execute_script[js_primitive3-py_primitive3\]] + expected: FAIL + + [test_primitives_set_by_execute_script["foobar"-foobar\]] + expected: FAIL + diff --git a/tests/wpt/metadata/webdriver/tests/refresh/refresh.py.ini b/tests/wpt/metadata/webdriver/tests/refresh/refresh.py.ini index c22bfd96462..c082415e07e 100644 --- a/tests/wpt/metadata/webdriver/tests/refresh/refresh.py.ini +++ b/tests/wpt/metadata/webdriver/tests/refresh/refresh.py.ini @@ -2,15 +2,9 @@ [test_history_pushstate] expected: FAIL - [test_basic] - expected: FAIL - [test_refresh_switches_to_parent_browsing_context] expected: FAIL [test_no_browsing_context] expected: ERROR - [test_dismissed_beforeunload] - expected: FAIL - |