use std::sync::Arc;
use tracing::{debug, instrument};
use viewpoint_cdp::CdpConnection;
use viewpoint_cdp::protocol::{DialogType, HandleJavaScriptDialogParams};
use crate::error::PageError;
#[derive(Debug)]
pub struct Dialog {
connection: Arc<CdpConnection>,
session_id: String,
dialog_type: DialogType,
message: String,
default_value: String,
handled: bool,
}
impl Dialog {
pub(crate) fn new(
connection: Arc<CdpConnection>,
session_id: String,
dialog_type: DialogType,
message: String,
default_value: Option<String>,
) -> Self {
Self {
connection,
session_id,
dialog_type,
message,
default_value: default_value.unwrap_or_default(),
handled: false,
}
}
pub fn type_(&self) -> DialogType {
self.dialog_type
}
pub fn message(&self) -> &str {
&self.message
}
pub fn default_value(&self) -> &str {
&self.default_value
}
#[instrument(level = "debug", skip(self), fields(dialog_type = %self.dialog_type))]
pub async fn accept(self) -> Result<(), PageError> {
if self.handled {
return Err(PageError::EvaluationFailed(
"Dialog has already been handled".to_string(),
));
}
debug!("Accepting dialog");
self.connection
.send_command::<_, serde_json::Value>(
"Page.handleJavaScriptDialog",
Some(HandleJavaScriptDialogParams {
accept: true,
prompt_text: None,
}),
Some(&self.session_id),
)
.await?;
std::mem::forget(self);
Ok(())
}
#[instrument(level = "debug", skip(self, text), fields(dialog_type = %self.dialog_type))]
pub async fn accept_with_text(self, text: impl Into<String>) -> Result<(), PageError> {
if self.handled {
return Err(PageError::EvaluationFailed(
"Dialog has already been handled".to_string(),
));
}
debug!("Accepting dialog with text");
self.connection
.send_command::<_, serde_json::Value>(
"Page.handleJavaScriptDialog",
Some(HandleJavaScriptDialogParams {
accept: true,
prompt_text: Some(text.into()),
}),
Some(&self.session_id),
)
.await?;
std::mem::forget(self);
Ok(())
}
#[instrument(level = "debug", skip(self), fields(dialog_type = %self.dialog_type))]
pub async fn dismiss(self) -> Result<(), PageError> {
if self.handled {
return Err(PageError::EvaluationFailed(
"Dialog has already been handled".to_string(),
));
}
debug!("Dismissing dialog");
self.connection
.send_command::<_, serde_json::Value>(
"Page.handleJavaScriptDialog",
Some(HandleJavaScriptDialogParams {
accept: false,
prompt_text: None,
}),
Some(&self.session_id),
)
.await?;
std::mem::forget(self);
Ok(())
}
}
impl Drop for Dialog {
fn drop(&mut self) {
if !self.handled {
tracing::warn!(
"Dialog of type {} was dropped without being handled. This may cause the page to freeze.",
self.dialog_type
);
}
}
}