mirror of
https://github.com/servo/servo.git
synced 2025-07-21 14:23:41 +01:00
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:
parent
3ce95b2ba5
commit
f0e10e63e2
10 changed files with 91 additions and 46 deletions
|
@ -172,6 +172,14 @@ impl SimpleDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_message(&mut self, text: String) {
|
||||||
|
match self {
|
||||||
|
SimpleDialog::Alert { message, .. } => *message = text,
|
||||||
|
SimpleDialog::Confirm { message, .. } => *message = text,
|
||||||
|
SimpleDialog::Prompt { message, .. } => *message = text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dismiss(&self) {
|
pub fn dismiss(&self) {
|
||||||
match self {
|
match self {
|
||||||
SimpleDialog::Alert {
|
SimpleDialog::Alert {
|
||||||
|
|
|
@ -166,6 +166,7 @@ pub enum WebDriverCommandMsg {
|
||||||
IpcSender<Result<Option<String>, ()>>,
|
IpcSender<Result<Option<String>, ()>>,
|
||||||
),
|
),
|
||||||
GetAlertText(WebViewId, IpcSender<Result<String, ()>>),
|
GetAlertText(WebViewId, IpcSender<Result<String, ()>>),
|
||||||
|
SendAlertText(WebViewId, String),
|
||||||
AddLoadStatusSender(WebViewId, IpcSender<WebDriverLoadStatus>),
|
AddLoadStatusSender(WebViewId, IpcSender<WebDriverLoadStatus>),
|
||||||
RemoveLoadStatusSender(WebViewId),
|
RemoveLoadStatusSender(WebViewId),
|
||||||
}
|
}
|
||||||
|
|
|
@ -827,10 +827,13 @@ impl Handler {
|
||||||
recv(self.load_status_receiver) -> res => {
|
recv(self.load_status_receiver) -> res => {
|
||||||
match res {
|
match res {
|
||||||
Ok(WebDriverLoadStatus::Blocked) => {
|
Ok(WebDriverLoadStatus::Blocked) => {
|
||||||
Err(WebDriverError::new(
|
// TODO: evaluate the correctness later
|
||||||
ErrorStatus::UnexpectedAlertOpen,
|
// Load status is block means an user prompt is shown.
|
||||||
"Load is blocked",
|
// 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)
|
Ok(WebDriverResponse::Void)
|
||||||
|
@ -2519,6 +2522,7 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler {
|
||||||
WebDriverCommand::DismissAlert => self.handle_dismiss_alert(),
|
WebDriverCommand::DismissAlert => self.handle_dismiss_alert(),
|
||||||
WebDriverCommand::AcceptAlert => self.handle_accept_alert(),
|
WebDriverCommand::AcceptAlert => self.handle_accept_alert(),
|
||||||
WebDriverCommand::GetAlertText => self.handle_get_alert_text(),
|
WebDriverCommand::GetAlertText => self.handle_get_alert_text(),
|
||||||
|
WebDriverCommand::SendAlertText(text) => self.handle_send_alert_text(text.text),
|
||||||
WebDriverCommand::DeleteCookies => self.handle_delete_cookies(),
|
WebDriverCommand::DeleteCookies => self.handle_delete_cookies(),
|
||||||
WebDriverCommand::DeleteCookie(name) => self.handle_delete_cookie(name),
|
WebDriverCommand::DeleteCookie(name) => self.handle_delete_cookie(name),
|
||||||
WebDriverCommand::GetTimeouts => self.handle_get_timeouts(),
|
WebDriverCommand::GetTimeouts => self.handle_get_timeouts(),
|
||||||
|
|
|
@ -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> {
|
pub(crate) fn handle_get_alert_text(&self) -> WebDriverResult<WebDriverResponse> {
|
||||||
// Step 1. If session's current top-level browsing context is no longer open,
|
// Step 1. If session's current top-level browsing context is no longer open,
|
||||||
// return error with error code no such window.
|
// 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>
|
/// <https://w3c.github.io/webdriver/#dfn-handle-any-user-prompts>
|
||||||
pub(crate) fn handle_any_user_prompts(
|
pub(crate) fn handle_any_user_prompts(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -620,6 +620,9 @@ impl App {
|
||||||
warn!("Failed to send response of GetAlertText: {error}");
|
warn!("Failed to send response of GetAlertText: {error}");
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
WebDriverCommandMsg::SendAlertText(webview_id, text) => {
|
||||||
|
running_state.set_alert_text_of_newest_dialog(webview_id, text);
|
||||||
|
},
|
||||||
WebDriverCommandMsg::TakeScreenshot(..) => {
|
WebDriverCommandMsg::TakeScreenshot(..) => {
|
||||||
warn!(
|
warn!(
|
||||||
"WebDriverCommand {:?} is still not moved from constellation to embedder",
|
"WebDriverCommand {:?} is still not moved from constellation to embedder",
|
||||||
|
|
|
@ -381,6 +381,14 @@ impl RunningAppState {
|
||||||
.and_then(|dialog| dialog.message())
|
.and_then(|dialog| dialog.message())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_alert_text_of_newest_dialog(&self, webview_id: WebViewId, text: String) {
|
||||||
|
if let Some(dialogs) = self.inner_mut().dialogs.get_mut(&webview_id) {
|
||||||
|
if let Some(dialog) = dialogs.last_mut() {
|
||||||
|
dialog.set_message(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_focused_webview_index(&self) -> Option<usize> {
|
pub(crate) fn get_focused_webview_index(&self) -> Option<usize> {
|
||||||
let focused_id = self.inner().focused_webview_id?;
|
let focused_id = self.inner().focused_webview_id?;
|
||||||
self.webviews()
|
self.webviews()
|
||||||
|
|
|
@ -168,6 +168,12 @@ impl Dialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_message(&mut self, text: String) {
|
||||||
|
if let Dialog::SimpleDialog(dialog) = self {
|
||||||
|
dialog.set_message(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, ctx: &egui::Context) -> bool {
|
pub fn update(&mut self, ctx: &egui::Context) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Dialog::File {
|
Dialog::File {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
expected: ERROR
|
expected: ERROR
|
||||||
|
|
||||||
[test_accept_confirm]
|
[test_accept_confirm]
|
||||||
expected: FAIL
|
expected: ERROR
|
||||||
|
|
||||||
[test_accept_prompt]
|
[test_accept_prompt]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
@ -11,11 +11,8 @@
|
||||||
[test_accept_in_popup_window]
|
[test_accept_in_popup_window]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_null_response_value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_accept_alert]
|
[test_accept_alert]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_unexpected_alert]
|
[test_no_browsing_context]
|
||||||
expected: FAIL
|
expected: ERROR
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
expected: ERROR
|
expected: ERROR
|
||||||
|
|
||||||
[test_dismiss_confirm]
|
[test_dismiss_confirm]
|
||||||
expected: FAIL
|
expected: ERROR
|
||||||
|
|
||||||
[test_dismiss_prompt]
|
[test_dismiss_prompt]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
@ -11,11 +11,8 @@
|
||||||
[test_dismiss_in_popup_window]
|
[test_dismiss_in_popup_window]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_null_response_value]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_dismiss_alert]
|
[test_dismiss_alert]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_unexpected_alert]
|
[test_no_browsing_context]
|
||||||
expected: FAIL
|
expected: ERROR
|
||||||
|
|
|
@ -1,31 +1,4 @@
|
||||||
[send.py]
|
[send.py]
|
||||||
[test_null_response_value]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
||||||
[test_invalid_input[None\]]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
||||||
[test_invalid_input[text1\]]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
||||||
[test_invalid_input[42\]]
|
|
||||||
expected: ERROR
|
|
||||||
|
|
||||||
[test_no_top_browsing_context]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_no_browsing_context]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_no_user_prompt]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_alert_element_not_interactable[alert\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_alert_element_not_interactable[confirm\]]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[test_chained_alert_element_not_interactable[alert\]]
|
[test_chained_alert_element_not_interactable[alert\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -43,6 +16,3 @@
|
||||||
|
|
||||||
[test_send_alert_text[Fed\\terer\]]
|
[test_send_alert_text[Fed\\terer\]]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[test_unexpected_alert]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue