webdriver: Implement send alert text (#38140)

Implement webdriver `SendAlertText` command

Tests:
https://github.com/longvatrong111/servo/actions/runs/16342669929
https://github.com/longvatrong111/servo/actions/runs/16342671477

cc: @xiaochengh

---------

Signed-off-by: batu_hoang <hoang.binh.trong@huawei.com>
Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
batu_hoang 2025-07-18 05:24:50 +08:00 committed by GitHub
parent 3ce95b2ba5
commit f0e10e63e2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 91 additions and 46 deletions

View file

@ -827,10 +827,13 @@ impl Handler {
recv(self.load_status_receiver) -> res => {
match res {
Ok(WebDriverLoadStatus::Blocked) => {
Err(WebDriverError::new(
ErrorStatus::UnexpectedAlertOpen,
"Load is blocked",
))
// TODO: evaluate the correctness later
// Load status is block means an user prompt is shown.
// Alot of tests expect this to return success
// then the user prompt is handled in the next command.
// If user prompt can't be handler, next command returns
// an error anyway.
Ok(WebDriverResponse::Void)
}
_ => {
Ok(WebDriverResponse::Void)
@ -2519,6 +2522,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler {
WebDriverCommand::DismissAlert => self.handle_dismiss_alert(),
WebDriverCommand::AcceptAlert => self.handle_accept_alert(),
WebDriverCommand::GetAlertText => self.handle_get_alert_text(),
WebDriverCommand::SendAlertText(text) => self.handle_send_alert_text(text.text),
WebDriverCommand::DeleteCookies => self.handle_delete_cookies(),
WebDriverCommand::DeleteCookie(name) => self.handle_delete_cookie(name),
WebDriverCommand::GetTimeouts => self.handle_get_timeouts(),

View file

@ -224,6 +224,7 @@ impl Handler {
}
}
/// <https://www.w3.org/TR/webdriver2/#dfn-get-alert-text>
pub(crate) fn handle_get_alert_text(&self) -> WebDriverResult<WebDriverResponse> {
// Step 1. If session's current top-level browsing context is no longer open,
// return error with error code no such window.
@ -255,6 +256,56 @@ impl Handler {
}
}
/// <https://www.w3.org/TR/webdriver2/#dfn-send-alert-text>
pub(crate) fn handle_send_alert_text(
&self,
text: String,
) -> WebDriverResult<WebDriverResponse> {
let webview_id = self.session()?.webview_id;
// Step 3. If session's current top-level browsing context is no longer open,
// return error with error code no such window.
self.verify_top_level_browsing_context_is_open(webview_id)?;
let (sender, receiver) = ipc::channel().unwrap();
self.send_message_to_embedder(WebDriverCommandMsg::CurrentUserPrompt(webview_id, sender))?;
match wait_for_script_response(receiver)? {
// Step 4. If the current user prompt is null, return error with error code no such alert.
None => Err(WebDriverError::new(
ErrorStatus::NoSuchAlert,
"No user prompt is currently active.",
)),
Some(prompt_type) => {
match prompt_type {
// Step 5. If the current user prompt is alert or confirm,
// return error with error code element not interactable.
WebDriverUserPrompt::Alert | WebDriverUserPrompt::Confirm => {
Err(WebDriverError::new(
ErrorStatus::ElementNotInteractable,
"Cannot send text to an alert or confirm prompt.",
))
},
// Step 5. If the current user prompt is prompt
WebDriverUserPrompt::Prompt => {
// Step 6. Send the text to the current user prompt.
self.send_message_to_embedder(WebDriverCommandMsg::SendAlertText(
webview_id, text,
))?;
Ok(WebDriverResponse::Void)
},
// Step 5. Otherwise, return error with error code unsupported operation.
_ => Err(WebDriverError::new(
ErrorStatus::UnsupportedOperation,
"Current user prompt type is not supported.",
)),
}
},
}
}
/// <https://w3c.github.io/webdriver/#dfn-handle-any-user-prompts>
pub(crate) fn handle_any_user_prompts(
&self,