Report exceptions for async script executions to webdriver (#27041)

Improving the accuracy of the async script execution for our webdriver
implementation allows us to run many more webdriver tests without
timeouts, which should help with
https://github.com/web-platform-tests/wpt/issues/24257.

Specification:
* https://w3c.github.io/webdriver/#dfn-clone-an-object
* https://w3c.github.io/webdriver/#execute-async-script

---
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #27036 and fix #27035 and fix #27031.
- [x] There are tests for these changes (but we don't run them in CI
yet)

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-04-25 02:50:00 -04:00 committed by GitHub
parent cbc363bedd
commit dc0c067c9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 115 additions and 36 deletions

View file

@ -1505,7 +1505,7 @@ impl Handler {
.iter()
.map(webdriver_value_to_js_argument)
.collect();
args_string.push("window.webdriverCallback".to_string());
args_string.push("resolve".to_string());
let timeout_script = if let Some(script_timeout) = self.session()?.script_timeout {
format!("setTimeout(webdriverTimeout, {});", script_timeout)
@ -1513,7 +1513,17 @@ impl Handler {
"".into()
};
let script = format!(
"{} (function() {{ {}\n }})({})",
r#"(function() {{
let webdriverPromise = new Promise(function(resolve, reject) {{
{}
(async function() {{
{}
}})({})
.then((v) => {{}}, (err) => reject(err))
}})
.then((v) => window.webdriverCallback(v), (r) => window.webdriverException(r))
.catch((r) => window.webdriverException(r));
}})();"#,
timeout_script,
func_body,
args_string.join(", "),
@ -1541,15 +1551,21 @@ impl Handler {
ErrorStatus::NoSuchWindow,
"Pipeline id not found in browsing context",
)),
Err(WebDriverJSError::JSError) => Err(WebDriverError::new(
Err(WebDriverJSError::JSException(_e)) => Err(WebDriverError::new(
ErrorStatus::JavascriptError,
"JS evaluation raised an exception",
)),
Err(WebDriverJSError::JSError) => Err(WebDriverError::new(
ErrorStatus::JavascriptError,
"JS evaluation raised an unknown exception",
)),
Err(WebDriverJSError::StaleElementReference) => Err(WebDriverError::new(
ErrorStatus::StaleElementReference,
"Stale element",
)),
Err(WebDriverJSError::Timeout) => Err(WebDriverError::new(ErrorStatus::Timeout, "")),
Err(WebDriverJSError::Timeout) => {
Err(WebDriverError::new(ErrorStatus::ScriptTimeout, ""))
},
Err(WebDriverJSError::UnknownType) => Err(WebDriverError::new(
ErrorStatus::UnsupportedOperation,
"Unsupported return type",