Skip to content

Use native WKWebView evaluateJavaScript on macOS#13

Open
bituq wants to merge 3 commits intohypothesi:mainfrom
bituq:fix/macos-native-js-eval
Open

Use native WKWebView evaluateJavaScript on macOS#13
bituq wants to merge 3 commits intohypothesi:mainfrom
bituq:fix/macos-native-js-eval

Conversation

@bituq
Copy link
Copy Markdown

@bituq bituq commented Mar 14, 2026

Fixes #12

Problem

On macOS, all JS execution tools (webview_execute_js, webview_dom_snapshot, webview_interact, read_logs) time out after 5 seconds. Screenshots and window listing work fine since they use native APIs.

The current approach injects a script via window.eval(), and the script sends results back through window.__TAURI__.event.emit() or invoke(). The eval succeeds (Rust gets no error), but the injected JS never reaches the IPC message handlers. The result never comes back, so it times out.

Fix

On macOS, use WKWebView.evaluateJavaScript:completionHandler: directly (via with_webview + objc2-web-kit), same pattern the screenshot code already uses. The completion handler gives us the result directly without needing any IPC roundtrip.

The existing eval + event listener approach stays as a fallback for other platforms.

Testing

Tested on macOS 15 (Darwin 25.3.0) with Tauri 2.10.3. Before the fix, every JS execution call timed out. After, webview_execute_js, webview_dom_snapshot, and webview_interact all work.

bituq and others added 3 commits March 14, 2026 16:36
The existing eval + IPC callback approach fails on macOS because
scripts injected via Tauri's window.eval() can't communicate back
to Rust through invoke() or event.emit(). The eval succeeds (no
error from Rust's side) but the injected JS never reaches the IPC
message handlers, causing a 5-second timeout on every call.

This adds a macOS-specific code path that uses WKWebView's native
evaluateJavaScript:completionHandler: API (via with_webview and
objc2-web-kit) to get script results directly from the completion
handler. This completely bypasses the eval->IPC->event pipeline.

The existing eval + event listener approach is kept as a fallback
for non-macOS platforms.

Fixes hypothesi#12
@bituq
Copy link
Copy Markdown
Author

bituq commented Mar 19, 2026

@yokuze Could you please review this PR? Otherwise this mcp server is unusable on MacOS.

@MarioGladiator
Copy link
Copy Markdown

@yokuze Could you please review this PR? Otherwise this mcp server is unusable on MacOS.

Hey, could you accept my request on discord, my user is "swezp."

@jaredmixpanel
Copy link
Copy Markdown

Confirming that I was also having this issue and this change does fix it. Please merge!

@yokuze
Copy link
Copy Markdown
Member

yokuze commented Mar 27, 2026

Confirming that I was also having this issue and this change does fix it. Please merge!

Thank you both for the bug report. Curious: Are you also on 15?

Copy link
Copy Markdown
Member

@yokuze yokuze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good, but the Rust linting is failing in CI.

Could you run

cargo clippy --fix

and

cargo fmt

And then fixup the original commits + force-push?

Thanks!

@jaredmixpanel
Copy link
Copy Markdown

@yokuze no, i'm on macOS 26.3

@yokuze
Copy link
Copy Markdown
Member

yokuze commented Mar 28, 2026

@yokuze no, i'm on macOS 26.3

Ok,thank you.

That's odd. I'd re-tested the methods the issue ticket mentioned on macOS 26 and they succeeded.

If either of you happen to have a payload that can reproduce the issue, that'd be valuable to have for future test cases.

If you leave the example payload(s) as a comment on this PR I will include them in a follow-up PR for regression testing.

Either way, after the formatting fixes are pushed to this branch, I'll merge.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JS execution always times out on macOS (screenshots work fine)

4 participants