mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Various fixes for webdriver conformance tests (#35737)
* servodriver: Ensure capabilities is always a non-empty value. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Serialize arguments object like an array. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Ensure script body is always valid JS. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Use current browsing context when getting element center point. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Propagate errors received from getting element center point. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Ensure opening a new window records a unique window handle. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Don't panic if script execution fails. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Do not update the current browsing context after closing a window. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Formatting. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * webdriver: Use more precise check for arguments exotic object. Signed-off-by: Josh Matthews <josh@joshmatthews.net> * Formatting. Signed-off-by: Josh Matthews <josh@joshmatthews.net> --------- Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
bc4ee8b56a
commit
21ecfdd088
6 changed files with 46 additions and 32 deletions
|
@ -5,6 +5,7 @@
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use base::id::{BrowsingContextId, PipelineId};
|
use base::id::{BrowsingContextId, PipelineId};
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
|
@ -20,7 +21,7 @@ use js::jsapi::{
|
||||||
};
|
};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::wrappers::{JS_CallFunctionName, JS_GetProperty, JS_HasOwnProperty, JS_TypeOfValue};
|
use js::rust::wrappers::{JS_CallFunctionName, JS_GetProperty, JS_HasOwnProperty, JS_TypeOfValue};
|
||||||
use js::rust::{HandleObject, HandleValue, IdVector};
|
use js::rust::{HandleObject, HandleValue, IdVector, ToString};
|
||||||
use net_traits::CookieSource::{HTTP, NonHTTP};
|
use net_traits::CookieSource::{HTTP, NonHTTP};
|
||||||
use net_traits::CoreResourceMsg::{DeleteCookies, GetCookiesDataForUrl, SetCookieForUrl};
|
use net_traits::CoreResourceMsg::{DeleteCookies, GetCookiesDataForUrl, SetCookieForUrl};
|
||||||
use net_traits::IpcSend;
|
use net_traits::IpcSend;
|
||||||
|
@ -42,7 +43,8 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::XMLSerializerBinding::XMLSerializerMethods;
|
use crate::dom::bindings::codegen::Bindings::XMLSerializerBinding::XMLSerializerMethods;
|
||||||
use crate::dom::bindings::conversions::{
|
use crate::dom::bindings::conversions::{
|
||||||
ConversionBehavior, ConversionResult, FromJSValConvertible, StringificationBehavior,
|
ConversionBehavior, ConversionResult, FromJSValConvertible, StringificationBehavior,
|
||||||
get_property, get_property_jsval, is_array_like, jsid_to_string, root_from_object,
|
get_property, get_property_jsval, is_array_like, jsid_to_string, jsstring_to_str,
|
||||||
|
root_from_object,
|
||||||
};
|
};
|
||||||
use crate::dom::bindings::error::{Error, throw_dom_exception};
|
use crate::dom::bindings::error::{Error, throw_dom_exception};
|
||||||
use crate::dom::bindings::inheritance::Castable;
|
use crate::dom::bindings::inheritance::Castable;
|
||||||
|
@ -168,6 +170,16 @@ unsafe fn object_has_to_json_property(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
/// <https://w3c.github.io/webdriver/#dfn-collection>
|
||||||
|
unsafe fn is_arguments_object(cx: *mut JSContext, value: HandleValue) -> bool {
|
||||||
|
rooted!(in(cx) let class_name = ToString(cx, value));
|
||||||
|
let Some(class_name) = NonNull::new(class_name.get()) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
jsstring_to_str(cx, class_name) == "[object Arguments]"
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub(crate) unsafe fn jsval_to_webdriver(
|
pub(crate) unsafe fn jsval_to_webdriver(
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
|
@ -212,7 +224,7 @@ pub(crate) unsafe fn jsval_to_webdriver(
|
||||||
});
|
});
|
||||||
let _ac = JSAutoRealm::new(cx, *object);
|
let _ac = JSAutoRealm::new(cx, *object);
|
||||||
|
|
||||||
if is_array_like(cx, val) {
|
if is_array_like(cx, val) || is_arguments_object(cx, val) {
|
||||||
let mut result: Vec<WebDriverJSValue> = Vec::new();
|
let mut result: Vec<WebDriverJSValue> = Vec::new();
|
||||||
|
|
||||||
let length = match get_property::<u32>(
|
let length = match get_property::<u32>(
|
||||||
|
|
|
@ -372,19 +372,15 @@ impl Handler {
|
||||||
PointerOrigin::Pointer => (start_x + x_offset, start_y + y_offset),
|
PointerOrigin::Pointer => (start_x + x_offset, start_y + y_offset),
|
||||||
PointerOrigin::Element(ref x) => {
|
PointerOrigin::Element(ref x) => {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
self.top_level_script_command(WebDriverScriptCommand::GetElementInViewCenterPoint(
|
self.browsing_context_script_command(
|
||||||
x.to_string(),
|
WebDriverScriptCommand::GetElementInViewCenterPoint(x.to_string(), sender),
|
||||||
sender,
|
)
|
||||||
))
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match receiver.recv().unwrap() {
|
let Some(point) = receiver.recv().unwrap()? else {
|
||||||
Ok(point) => match point {
|
return Err(ErrorStatus::UnknownError);
|
||||||
Some(point) => point,
|
};
|
||||||
None => return Err(ErrorStatus::UnknownError),
|
point
|
||||||
},
|
|
||||||
Err(_) => return Err(ErrorStatus::UnknownError),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -897,14 +897,13 @@ impl Handler {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let webview_id = self.focus_webview_id()?;
|
|
||||||
let browsing_context_id = BrowsingContextId::from(webview_id);
|
|
||||||
let session = self.session_mut().unwrap();
|
|
||||||
session.webview_id = webview_id;
|
|
||||||
session.browsing_context_id = browsing_context_id;
|
|
||||||
|
|
||||||
Ok(WebDriverResponse::CloseWindow(CloseWindowResponse(
|
Ok(WebDriverResponse::CloseWindow(CloseWindowResponse(
|
||||||
session.window_handles.values().cloned().collect(),
|
self.session()
|
||||||
|
.unwrap()
|
||||||
|
.window_handles
|
||||||
|
.values()
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,17 +923,18 @@ impl Handler {
|
||||||
.send(ConstellationMsg::WebDriverCommand(cmd_msg))
|
.send(ConstellationMsg::WebDriverCommand(cmd_msg))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let mut handle = self.session.as_ref().unwrap().id.to_string();
|
||||||
if let Ok(new_webview_id) = receiver.recv() {
|
if let Ok(new_webview_id) = receiver.recv() {
|
||||||
let session = self.session_mut().unwrap();
|
let session = self.session_mut().unwrap();
|
||||||
session.webview_id = new_webview_id;
|
session.webview_id = new_webview_id;
|
||||||
session.browsing_context_id = BrowsingContextId::from(new_webview_id);
|
session.browsing_context_id = BrowsingContextId::from(new_webview_id);
|
||||||
let new_handle = Uuid::new_v4().to_string();
|
let new_handle = Uuid::new_v4().to_string();
|
||||||
|
handle = new_handle.clone();
|
||||||
session.window_handles.insert(new_webview_id, new_handle);
|
session.window_handles.insert(new_webview_id, new_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.wait_for_load();
|
let _ = self.wait_for_load();
|
||||||
|
|
||||||
let handle = self.session.as_ref().unwrap().id.to_string();
|
|
||||||
Ok(WebDriverResponse::NewWindow(NewWindowResponse {
|
Ok(WebDriverResponse::NewWindow(NewWindowResponse {
|
||||||
handle,
|
handle,
|
||||||
typ: "tab".to_string(),
|
typ: "tab".to_string(),
|
||||||
|
@ -1458,7 +1458,7 @@ impl Handler {
|
||||||
// new Function() and then takes the resulting function and executes
|
// new Function() and then takes the resulting function and executes
|
||||||
// it with a vec of arguments.
|
// it with a vec of arguments.
|
||||||
let script = format!(
|
let script = format!(
|
||||||
"(function() {{ {} }})({})",
|
"(function() {{ {}\n }})({})",
|
||||||
func_body,
|
func_body,
|
||||||
args_string.join(", ")
|
args_string.join(", ")
|
||||||
);
|
);
|
||||||
|
@ -1467,7 +1467,9 @@ impl Handler {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let command = WebDriverScriptCommand::ExecuteScript(script, sender);
|
let command = WebDriverScriptCommand::ExecuteScript(script, sender);
|
||||||
self.browsing_context_script_command(command)?;
|
self.browsing_context_script_command(command)?;
|
||||||
let result = receiver.recv().unwrap();
|
let result = receiver
|
||||||
|
.recv()
|
||||||
|
.unwrap_or(Err(WebDriverJSError::BrowsingContextNotFound));
|
||||||
self.postprocess_js_result(result)
|
self.postprocess_js_result(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,7 +1493,7 @@ impl Handler {
|
||||||
"".into()
|
"".into()
|
||||||
};
|
};
|
||||||
let script = format!(
|
let script = format!(
|
||||||
"{} (function() {{ {} }})({})",
|
"{} (function() {{ {}\n }})({})",
|
||||||
timeout_script,
|
timeout_script,
|
||||||
func_body,
|
func_body,
|
||||||
args_string.join(", "),
|
args_string.join(", "),
|
||||||
|
@ -1501,7 +1503,9 @@ impl Handler {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let command = WebDriverScriptCommand::ExecuteAsyncScript(script, sender);
|
let command = WebDriverScriptCommand::ExecuteAsyncScript(script, sender);
|
||||||
self.browsing_context_script_command(command)?;
|
self.browsing_context_script_command(command)?;
|
||||||
let result = receiver.recv().unwrap();
|
let result = receiver
|
||||||
|
.recv()
|
||||||
|
.unwrap_or(Err(WebDriverJSError::BrowsingContextNotFound));
|
||||||
self.postprocess_js_result(result)
|
self.postprocess_js_result(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1514,7 +1518,7 @@ impl Handler {
|
||||||
serde_json::to_value(SendableWebDriverJSValue(value))?,
|
serde_json::to_value(SendableWebDriverJSValue(value))?,
|
||||||
))),
|
))),
|
||||||
Err(WebDriverJSError::BrowsingContextNotFound) => Err(WebDriverError::new(
|
Err(WebDriverJSError::BrowsingContextNotFound) => Err(WebDriverError::new(
|
||||||
ErrorStatus::JavascriptError,
|
ErrorStatus::NoSuchWindow,
|
||||||
"Pipeline id not found in browsing context",
|
"Pipeline id not found in browsing context",
|
||||||
)),
|
)),
|
||||||
Err(WebDriverJSError::JSError) => Err(WebDriverError::new(
|
Err(WebDriverJSError::JSError) => Err(WebDriverError::new(
|
||||||
|
|
4
tests/wpt/meta/MANIFEST.json
vendored
4
tests/wpt/meta/MANIFEST.json
vendored
|
@ -507579,7 +507579,7 @@
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"servodriver.py": [
|
"servodriver.py": [
|
||||||
"18035f9331e0d5df1c3fa916ce33a8866bea091a",
|
"bd16d7987e539a3325d88876982462ea1a3eb638",
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"webkit.py": [
|
"webkit.py": [
|
||||||
|
@ -507645,7 +507645,7 @@
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"executorservodriver.py": [
|
"executorservodriver.py": [
|
||||||
"7e4aee5e7af7b9719b4ccb1f5a0a7c7cb3aa1653",
|
"e27b111ee8b7c4cdff4a0aee5c010d402efff263",
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"executorwebdriver.py": [
|
"executorwebdriver.py": [
|
||||||
|
|
|
@ -48,11 +48,13 @@ def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
|
||||||
"server_config": config,
|
"server_config": config,
|
||||||
"user_stylesheets": kwargs.get("user_stylesheets"),
|
"user_stylesheets": kwargs.get("user_stylesheets"),
|
||||||
"headless": kwargs.get("headless"),
|
"headless": kwargs.get("headless"),
|
||||||
|
"capabilities": kwargs.get("capabilities"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def executor_kwargs(logger, test_type, test_environment, run_info_data, **kwargs):
|
def executor_kwargs(logger, test_type, test_environment, run_info_data, **kwargs):
|
||||||
rv = base_executor_kwargs(test_type, test_environment, run_info_data, **kwargs)
|
rv = base_executor_kwargs(test_type, test_environment, run_info_data, **kwargs)
|
||||||
|
rv['capabilities'] = {}
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ class ServoWebDriverTestharnessExecutor(WebDriverTestharnessExecutor):
|
||||||
protocol_cls = ServoWebDriverProtocol
|
protocol_cls = ServoWebDriverProtocol
|
||||||
|
|
||||||
def __init__(self, logger, browser, server_config, timeout_multiplier=1,
|
def __init__(self, logger, browser, server_config, timeout_multiplier=1,
|
||||||
close_after_done=True, capabilities={}, debug_info=None,
|
close_after_done=True, capabilities=None, debug_info=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
WebDriverTestharnessExecutor.__init__(self, logger, browser, server_config,
|
WebDriverTestharnessExecutor.__init__(self, logger, browser, server_config,
|
||||||
timeout_multiplier, capabilities=capabilities,
|
timeout_multiplier, capabilities=capabilities,
|
||||||
|
@ -96,7 +96,7 @@ class ServoWebDriverRefTestExecutor(WebDriverRefTestExecutor):
|
||||||
protocol_cls = ServoWebDriverProtocol
|
protocol_cls = ServoWebDriverProtocol
|
||||||
|
|
||||||
def __init__(self, logger, browser, server_config, timeout_multiplier=1,
|
def __init__(self, logger, browser, server_config, timeout_multiplier=1,
|
||||||
screenshot_cache=None, capabilities={}, debug_info=None,
|
screenshot_cache=None, capabilities=None, debug_info=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
WebDriverRefTestExecutor.__init__(self, logger, browser, server_config,
|
WebDriverRefTestExecutor.__init__(self, logger, browser, server_config,
|
||||||
timeout_multiplier, screenshot_cache,
|
timeout_multiplier, screenshot_cache,
|
||||||
|
@ -114,7 +114,7 @@ class ServoWebDriverCrashtestExecutor(WebDriverCrashtestExecutor):
|
||||||
protocol_cls = ServoWebDriverProtocol
|
protocol_cls = ServoWebDriverProtocol
|
||||||
|
|
||||||
def __init__(self, logger, browser, server_config, timeout_multiplier=1,
|
def __init__(self, logger, browser, server_config, timeout_multiplier=1,
|
||||||
screenshot_cache=None, capabilities={}, debug_info=None,
|
screenshot_cache=None, capabilities=None, debug_info=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
WebDriverCrashtestExecutor.__init__(self, logger, browser, server_config,
|
WebDriverCrashtestExecutor.__init__(self, logger, browser, server_config,
|
||||||
timeout_multiplier, screenshot_cache,
|
timeout_multiplier, screenshot_cache,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue