Skip to content

Commit be76fb1

Browse files
WebDriver support (#1972)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 951f04b commit be76fb1

16 files changed

Lines changed: 992 additions & 13 deletions

File tree

.changes/config.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@
290290
"create-tauri-app": {
291291
"path": "./tooling/create-tauri-app",
292292
"manager": "javascript"
293+
},
294+
"tauri-driver": {
295+
"path": "./tooling/webdriver",
296+
"manager": "rust"
293297
}
294298
}
295-
}
299+
}

.changes/tauri-driver.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-driver": patch
3+
---
4+
5+
Initial release including Linux and Windows support.

.changes/webdriver.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-runtime-wry": patch
3+
---
4+
5+
Add webdriver support to Tauri.

core/tauri-runtime-wry/src/lib.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,13 @@ use wry::{
5555
};
5656

5757
use std::{
58-
collections::HashMap,
58+
collections::{
59+
hash_map::Entry::{Occupied, Vacant},
60+
HashMap,
61+
},
5962
convert::TryFrom,
6063
fs::read,
64+
path::PathBuf,
6165
sync::{
6266
atomic::{AtomicBool, Ordering},
6367
mpsc::{channel, Sender},
@@ -75,8 +79,10 @@ mod mime_type;
7579
use mime_type::MimeType;
7680

7781
type MainTask = Arc<Mutex<Option<Box<dyn FnOnce() + Send>>>>;
78-
type CreateWebviewHandler =
79-
Box<dyn FnOnce(&EventLoopWindowTarget<Message>) -> Result<WebviewWrapper> + Send>;
82+
type WebContextStore = Mutex<HashMap<Option<PathBuf>, WebContext>>;
83+
type CreateWebviewHandler = Box<
84+
dyn FnOnce(&EventLoopWindowTarget<Message>, &WebContextStore) -> Result<WebviewWrapper> + Send,
85+
>;
8086
type WindowEventHandler = Box<dyn Fn(&WindowEvent) + Send>;
8187
type WindowEventListeners = Arc<Mutex<HashMap<Uuid, WindowEventHandler>>>;
8288
type GlobalShortcutListeners = Arc<Mutex<HashMap<AcceleratorId, Box<dyn Fn() + Send>>>>;
@@ -861,9 +867,9 @@ impl Dispatch for WryDispatcher {
861867
.context
862868
.proxy
863869
.send_event(Message::CreateWebview(
864-
Arc::new(Mutex::new(Some(Box::new(move |event_loop| {
865-
create_webview(event_loop, context, pending)
866-
})))),
870+
Arc::new(Mutex::new(Some(Box::new(
871+
move |event_loop, web_context| create_webview(event_loop, web_context, context, pending),
872+
)))),
867873
tx,
868874
))
869875
.map_err(|_| Error::FailedToSendMessage)?;
@@ -1137,6 +1143,7 @@ pub struct Wry {
11371143
clipboard_manager_handle: ClipboardManagerWrapper,
11381144
is_event_loop_running: Arc<AtomicBool>,
11391145
event_loop: EventLoop<Message>,
1146+
web_context: WebContextStore,
11401147
webviews: Arc<Mutex<HashMap<WindowId, WebviewWrapper>>>,
11411148
window_event_listeners: WindowEventListeners,
11421149
#[cfg(feature = "menu")]
@@ -1167,9 +1174,11 @@ impl RuntimeHandle for WryHandle {
11671174
.dispatcher_context
11681175
.proxy
11691176
.send_event(Message::CreateWebview(
1170-
Arc::new(Mutex::new(Some(Box::new(move |event_loop| {
1171-
create_webview(event_loop, dispatcher_context, pending)
1172-
})))),
1177+
Arc::new(Mutex::new(Some(Box::new(
1178+
move |event_loop, web_context| {
1179+
create_webview(event_loop, web_context, dispatcher_context, pending)
1180+
},
1181+
)))),
11731182
tx,
11741183
))
11751184
.map_err(|_| Error::FailedToSendMessage)?;
@@ -1231,6 +1240,7 @@ impl Runtime for Wry {
12311240
clipboard_manager_handle,
12321241
is_event_loop_running,
12331242
event_loop,
1243+
web_context: Default::default(),
12341244
webviews: Default::default(),
12351245
window_event_listeners: Default::default(),
12361246
#[cfg(feature = "menu")]
@@ -1269,6 +1279,7 @@ impl Runtime for Wry {
12691279
let proxy = self.event_loop.create_proxy();
12701280
let webview = create_webview(
12711281
&self.event_loop,
1282+
&self.web_context,
12721283
DispatcherContext {
12731284
main_thread_id: self.main_thread_id,
12741285
is_event_loop_running: self.is_event_loop_running.clone(),
@@ -1343,6 +1354,7 @@ impl Runtime for Wry {
13431354
fn run_iteration<F: Fn(RunEvent) + 'static>(&mut self, callback: F) -> RunIteration {
13441355
use wry::application::platform::run_return::EventLoopExtRunReturn;
13451356
let webviews = self.webviews.clone();
1357+
let web_context = &self.web_context;
13461358
let window_event_listeners = self.window_event_listeners.clone();
13471359
#[cfg(feature = "menu")]
13481360
let menu_event_listeners = self.menu_event_listeners.clone();
@@ -1377,6 +1389,7 @@ impl Runtime for Wry {
13771389
#[cfg(feature = "system-tray")]
13781390
tray_context: tray_context.clone(),
13791391
},
1392+
web_context,
13801393
);
13811394
});
13821395
self.is_event_loop_running.store(false, Ordering::Relaxed);
@@ -1387,6 +1400,7 @@ impl Runtime for Wry {
13871400
fn run<F: Fn(RunEvent) + 'static>(self, callback: F) {
13881401
self.is_event_loop_running.store(true, Ordering::Relaxed);
13891402
let webviews = self.webviews.clone();
1403+
let web_context = self.web_context;
13901404
let window_event_listeners = self.window_event_listeners.clone();
13911405
#[cfg(feature = "menu")]
13921406
let menu_event_listeners = self.menu_event_listeners.clone();
@@ -1413,6 +1427,7 @@ impl Runtime for Wry {
14131427
#[cfg(feature = "system-tray")]
14141428
tray_context: tray_context.clone(),
14151429
},
1430+
&web_context,
14161431
);
14171432
})
14181433
}
@@ -1436,6 +1451,7 @@ fn handle_event_loop(
14361451
event_loop: &EventLoopWindowTarget<Message>,
14371452
control_flow: &mut ControlFlow,
14381453
context: EventLoopIterationContext<'_>,
1454+
web_context: &WebContextStore,
14391455
) -> RunIteration {
14401456
let EventLoopIterationContext {
14411457
callback,
@@ -1689,7 +1705,7 @@ fn handle_event_loop(
16891705
let mut lock = handler.lock().expect("poisoned create webview handler");
16901706
std::mem::take(&mut *lock).unwrap()
16911707
};
1692-
match handler(event_loop) {
1708+
match handler(event_loop, web_context) {
16931709
Ok(webview) => {
16941710
let window_id = webview.inner.window().id();
16951711
webviews.insert(window_id, webview);
@@ -1700,6 +1716,7 @@ fn handle_event_loop(
17001716
}
17011717
}
17021718
}
1719+
17031720
#[cfg(feature = "system-tray")]
17041721
Message::Tray(tray_message) => match tray_message {
17051722
TrayMessage::UpdateItem(menu_id, update) => {
@@ -1817,6 +1834,7 @@ fn center_window(window: &Window) -> Result<()> {
18171834

18181835
fn create_webview<P: Params<Runtime = Wry>>(
18191836
event_loop: &EventLoopWindowTarget<Message>,
1837+
web_context: &WebContextStore,
18201838
context: DispatcherContext,
18211839
pending: PendingWindow<P>,
18221840
) -> Result<WebviewWrapper> {
@@ -1877,13 +1895,27 @@ fn create_webview<P: Params<Runtime = Wry>>(
18771895
.map_err(|_| wry::Error::InitScriptError)
18781896
});
18791897
}
1880-
let context = WebContext::new(webview_attributes.data_directory);
1881-
webview_builder = webview_builder.with_web_context(&context);
1898+
18821899
for script in webview_attributes.initialization_scripts {
18831900
webview_builder = webview_builder.with_initialization_script(&script);
18841901
}
18851902

1903+
let mut web_context = web_context.lock().expect("poisoned WebContext store");
1904+
let is_first_context = web_context.is_empty();
1905+
let web_context = match web_context.entry(webview_attributes.data_directory) {
1906+
Occupied(occupied) => occupied.into_mut(),
1907+
Vacant(vacant) => {
1908+
let mut web_context = WebContext::new(vacant.key().clone());
1909+
web_context.set_allows_automation(match std::env::var("TAURI_AUTOMATION").as_deref() {
1910+
Ok("true") => is_first_context,
1911+
_ => false,
1912+
});
1913+
vacant.insert(web_context)
1914+
}
1915+
};
1916+
18861917
let webview = webview_builder
1918+
.with_web_context(web_context)
18871919
.build()
18881920
.map_err(|e| Error::CreateWebview(Box::new(e)))?;
18891921

tooling/webdriver/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/target
2+
.DS_Store
3+
*.rs.bk
4+
*~
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Copyright {20\d{2}(-20\d{2})?} Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT

0 commit comments

Comments
 (0)