tauri_plugin_webdriver_automation/
lib.rs1use std::collections::HashMap;
8use std::sync::Mutex;
9
10use tauri::{Manager, Runtime, State};
11
12mod server;
13
14#[tauri::command]
17async fn resolve<R: Runtime>(
18 _app: tauri::AppHandle<R>,
19 webdriver: State<'_, WebDriverState>,
20 id: String,
21 result: Option<serde_json::Value>,
22) -> Result<(), ()> {
23 webdriver
24 .pending_scripts
25 .lock()
26 .expect("failed to lock pending scripts")
27 .remove(&id)
28 .expect("no pending script with that id")
29 .send(result.unwrap_or_default())
30 .expect("failed to send script result");
31 Ok(())
32}
33
34pub(crate) struct WebDriverState {
37 pub pending_scripts: Mutex<HashMap<String, tokio::sync::oneshot::Sender<serde_json::Value>>>,
38}
39
40pub fn init<R: Runtime>() -> tauri::plugin::TauriPlugin<R> {
43 let (webview_created_tx, webview_created_rx) = tokio::sync::broadcast::channel(16);
44
45 tauri::plugin::Builder::new("webdriver-automation")
46 .invoke_handler(tauri::generate_handler![resolve])
47 .js_init_script(include_str!("init.js").to_string())
48 .on_webview_ready(move |webview| {
49 webview_created_tx
50 .send(
51 webview
52 .get_webview_window(webview.label())
53 .unwrap_or_else(|| {
54 panic!("failed to get webview window for label {}", webview.label())
55 }),
56 )
57 .unwrap_or_default();
58 })
59 .setup(move |app, _api| {
60 app.manage(WebDriverState {
61 pending_scripts: Mutex::new(HashMap::new()),
62 });
63
64 app.add_capability(
65 tauri::ipc::CapabilityBuilder::new("webdriver-automation")
66 .local(true)
67 .window("*")
68 .remote("http://*".into())
69 .remote("https://*".into())
70 .permission("webdriver-automation:default"),
71 )?;
72
73 let app_handle = app.clone();
75 let rx = webview_created_rx.resubscribe();
76 tauri::async_runtime::spawn(async move {
77 server::start(app_handle, rx).await;
78 });
79
80 Ok(())
81 })
82 .build()
83}
84
85pub(crate) fn window_by_label<R: Runtime>(
88 app: &tauri::AppHandle<R>,
89 label: Option<&str>,
90) -> Option<tauri::WebviewWindow<R>> {
91 if let Some(label) = label {
92 app.get_webview_window(label)
93 } else {
94 app.get_webview_window("main")
95 .or_else(|| app.webview_windows().into_values().next())
96 }
97}
98