use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct ElementBbox {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[schemars(deny_unknown_fields)]
pub struct ElementRect {
pub x: f64,
pub y: f64,
pub width: f64,
pub height: f64,
pub top: f64,
pub right: f64,
pub bottom: f64,
pub left: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ElementState {
pub visible: bool,
pub enabled: bool,
pub focused: bool,
pub rect: ElementRect,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub value: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub checked: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub selected_options: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub text_content: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ElementIdentifier {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ui_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub test_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub awas_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub html_id: Option<String>,
pub xpath: String,
pub selector: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeElement {
pub id: String,
#[serde(rename = "type")]
pub element_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub actions: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub custom_actions: Option<Vec<String>>,
pub identifier: ElementIdentifier,
pub state: ElementState,
pub registered_at: i64,
pub mounted: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub bbox: Option<ElementBbox>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub visible: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tag_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub aria_label: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub accessible_name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub text: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ComponentActionInfo {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeComponent {
pub id: String,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub actions: Vec<ComponentActionInfo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub element_ids: Option<Vec<String>>,
pub registered_at: i64,
pub mounted: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct WaitOptions {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub visible: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub enabled: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub focused: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timeout: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub interval: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ElementActionRequest {
pub action: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub params: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub wait_options: Option<WaitOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ComponentActionRequest {
pub action: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub params: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct ActionResponse {
pub success: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub element_state: Option<ElementState>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub result: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stack: Option<String>,
pub duration_ms: u64,
pub timestamp: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub effect_verification: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct DiscoveryRequest {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub root: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub interactive_only: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub include_hidden: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub types: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub selector: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct DiscoveredElement {
pub id: String,
#[serde(rename = "type")]
pub element_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
pub tag_name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub accessible_name: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub actions: Vec<String>,
pub state: ElementState,
pub registered: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct DiscoveryResponse {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub elements: Vec<DiscoveredElement>,
pub total: usize,
pub duration_ms: u64,
pub timestamp: i64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct WorkflowInfo {
pub id: String,
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub step_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeModalInfo {
pub id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub r#type: Option<String>,
pub blocking: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dismissible: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub z_index: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub has_backdrop: Option<bool>,
pub detected_at: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeModalStack {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub modals: Vec<UIBridgeModalInfo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub top_modal: Option<UIBridgeModalInfo>,
pub has_blocking_modal: bool,
pub count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeCapturedToast {
pub id: String,
pub message: String,
pub level: String,
pub appeared_at: i64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dismissed_at: Option<i64>,
pub visible: bool,
pub duration_ms: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeToastContext {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub active: Vec<UIBridgeCapturedToast>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub recent: Vec<UIBridgeCapturedToast>,
pub total_captured: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeUndoContext {
pub can_undo: bool,
pub can_redo: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub undo_description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub redo_description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub undo_depth: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub redo_depth: Option<usize>,
pub summary: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[schemars(deny_unknown_fields)]
pub struct UIBridgeSnapshot {
pub timestamp: i64,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub elements: Vec<UIBridgeElement>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub components: Vec<UIBridgeComponent>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub workflows: Vec<WorkflowInfo>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub modal_stack: Option<UIBridgeModalStack>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub toasts: Option<UIBridgeToastContext>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub undo_redo: Option<UIBridgeUndoContext>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub current_route: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub segments: Vec<String>,
}