Skip to content

Commit ddd3997

Browse files
goosewobblerclaude
andauthored
feat: tauri service (#6)
* feat: extract `native-utils` * chore: remove test:integration script * chore: add `shell: true` * refactor: remove abstract classes * chore: pivot, remove native utils * chore: update specs * chore: ignore tauri dist * feat: tauri service first pass * chore: update lockfile * chore: use correct package name * chore: tauri E2E wiring * chore: update labels * chore: update filter * chore: remove verbose turbo logs * chore: fix build scripts * chore: install tauri deps on linux * chore: fix matrix issues * chore: fix unit * chore: use github code for skip * chore: fix framework filtering in matrix * chore: fix package test error * chore: skip tauri macos e2es properly * test: fix no-binary path issue * chore: add debug * chore: fix matrix * chore: add dummy icon * test: fix no-binary path issue * chore: fix tauri compilation * chore: add xcb libs * refactor: move tauri app * chore: install tauri driver * chore: fixed binary path resolution * chore: add windows icon * fix: change tauri to chrome during onPrepare * chore: update ico * chore: set default chromium version * chore: fix path issue * chore: Webkit Webdriver shenanigans * fix: improved multiremote handling * chore: remove redundant init-e2es task * refactor: abstract logger * chore: don't hard code path separator * chore: don't specify nativeDriverPath * chore: add native-utils dep * chore: update lockfile * test: update for logger changes * fix: tauri path issues * fix: add comprehensive Chrome flags and fix app args passing for Tauri on Linux CI - Add extensive Chrome flags needed for headless Linux CI environments - Add Chrome prefs to disable password manager and notifications - Fix bug where tauri:options.args weren't being passed to the app binary - Add execute permissions check for Tauri binaries on Linux - Add debug logging for binary path and args These changes should fix the 'DevToolsActivePort file doesn't exist' error on Linux CI by ensuring: 1. Chrome has all necessary flags for headless operation 2. The Tauri app binary has execute permissions 3. App arguments are correctly passed to the binary * feat: add comprehensive environment diagnostics for Tauri tests Add detailed diagnostic checks that run before each test session to help troubleshoot Linux CI issues: - Check platform, Node version, DISPLAY, and XVFB status - Verify binary permissions and executability - Check shared library dependencies with ldd - Test if binary can execute at all - Verify Chrome/Chromium system dependencies - Check WebKitWebDriver availability - Show disk space availability - Log all Chrome args being passed to ChromeDriver This will help identify the root cause of 'DevToolsActivePort file doesn't exist' errors by providing visibility into: - Missing shared libraries (webkit2gtk, GTK, etc.) - Permission issues - Binary execution failures - Missing system dependencies * fix: set DISPLAY in worker process and configure tauri-driver connection The DISPLAY environment variable was not available in the WDIO worker process, causing ChromeDriver and diagnostic commands to fail when trying to launch the Tauri binary with GTK. This fix: 1. Sets DISPLAY in the worker process environment (onWorkerStart) so that ChromeDriver and all child processes have access to the X server 2. Configures WDIO to connect to tauri-driver's WebDriver endpoint instead of spawning a separate ChromeDriver instance 3. Keeps DISPLAY set when spawning tauri-driver for redundancy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: properly configure WDIO to connect to tauri-driver Following the official Tauri WebDriverIO example, this commit fixes the integration by: 1. NOT converting browserName from 'tauri' to 'chrome' - this was causing WDIO to spawn ChromeDriver instead of connecting to tauri-driver 2. Setting hostname to '127.0.0.1' (not 'localhost') to match Tauri docs 3. Removing all Chrome-specific options (goog:chromeOptions, args, etc) since tauri-driver handles this internally 4. Keeping browserName as 'tauri' and only resolving the binary path in tauri:options.application This allows WDIO to properly connect to tauri-driver which then manages the WebKit WebDriver session. References: - https://v2.tauri.app/develop/tests/webdriver/example/webdriverio/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: pre-build Tauri apps in OS-specific jobs for faster E2E tests This optimization significantly improves CI performance by building Tauri applications once per OS and reusing the binaries across all test types. Changes: 1. Created _ci-build-tauri-apps.reusable.yml workflow - Builds Tauri apps for a specific OS - Uploads binaries as artifacts (per OS, unlike packages) - Follows the same pattern as _ci-build.reusable.yml 2. Updated ci.yml to add build-tauri-apps jobs - build-tauri-apps-linux: Builds Tauri apps on Linux - build-tauri-apps-windows: Builds Tauri apps on Windows - Both run in parallel with other jobs after package build - e2e-tauri-matrix now depends on these jobs 3. Updated _ci-e2e-tauri.reusable.yml to download pre-built binaries - Removed Tauri app build step (was rebuilding for each test type) - Added download step for Tauri app binaries - Added tauri_cache_key input parameter Benefits: - Much faster: Build once (~2-5 min) vs rebuild 4x per OS - Consistent: All test types on same OS use identical binaries - Parallel: Build jobs run alongside other jobs - Cheaper: Less compute time = lower GitHub Actions costs Example: On Linux with 4 test types (standard, window, multiremote, standalone), this saves ~6-15 minutes of build time per run. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: remove browserName from capabilities to fix multiremote The multiremote tests were failing because WDIO was trying to spawn a driver for browserName='tauri', which doesn't exist. Following the official Tauri WebDriverIO example, we should NOT set browserName at all when using tauri-driver. Changes: 1. Delete browserName from capabilities after validation - This prevents WDIO from trying to spawn a driver - When hostname/port are set, WDIO connects directly to tauri-driver 2. Simplify onWorkerStart to use already-resolved binary path - The binary path is resolved in onPrepare and stored in capabilities - No need to call getTauriBinaryPath again in onWorkerStart - Just verify the file exists 3. Add existsSync import for binary verification This fixes the multiremote error: "Unknown browser name 'tauri'. Make sure to pick from one of the following chrome,googlechrome,chromium..." 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: make browserName optional and remove from test configs Following the official Tauri WebDriverIO example more closely, browserName should NOT be set in capabilities at all. WDIO uses browserName to determine which driver to spawn, but we're connecting directly to tauri-driver via hostname/port. Changes: 1. Updated wdio.tauri.conf.ts - Removed browserName from all capabilities (standard and multiremote) - Made browserName optional in local TauriCapability type 2. Updated packages/tauri-service/src/types.ts - Made browserName optional in TauriCapabilities interface - Allows configs to omit browserName entirely 3. Updated packages/tauri-service/src/launcher.ts - Changed validation to accept missing browserName - Only validate if browserName is present (must be 'tauri') - Only delete browserName if it exists This matches the official Tauri example which doesn't set browserName: https://v2.tauri.app/develop/tests/webdriver/example/webdriverio/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: resolve Tauri build issues on Linux and Windows Fixed two critical issues with the Tauri app build workflow: 1. Linux: Missing XCB library dependencies - Added all required X11/XCB development packages - Specifically: libxcb-shape0-dev, libxcb-xfixes0-dev, and related libs - These are needed for linking Tauri binaries on Linux - Error was: "unable to find library -lxcb-shape" 2. Windows: PowerShell Compress-Archive timestamp issue - Rust target directories can have files with timestamps outside the valid ZIP file range (1980-2107) - PowerShell's Compress-Archive fails with: "The DateTimeOffset specified cannot be converted into a Zip file timestamp" - Solution: Normalize file timestamps before compression - Files with invalid timestamps are set to 2020-01-01 Changes: - Updated _ci-build-tauri-apps.reusable.yml to install all X11/XCB deps - Updated upload-archive action to normalize timestamps on Windows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: set hostname and port in capabilities for standalone mode Standalone tests use WDIO's remote() function which reads connection settings from capabilities directly, not from the config object. Error: "No browserName defined in capabilities nor hostname or port found!" Solution: Set hostname and port in capabilities as well as config: - cap.hostname = '127.0.0.1' - cap.port = 4444 (or configured tauriDriverPort) This ensures both normal and standalone modes can connect to tauri-driver. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: set hostname and port in wdio config, not in onPrepare hook The previous approach of setting hostname/port in the service's onPrepare hook didn't work because WDIO reads the config before the hook runs. Following the official Tauri WebDriverIO example, hostname and port must be set directly in the wdio config object: ```javascript export const config = { hostname: '127.0.0.1', port: 4444, // ... other config } ``` This ensures WDIO connects to tauri-driver for all test modes (standard, multiremote, and standalone). Changes: 1. Added hostname and port to wdio.tauri.conf.ts export 2. Simplified launcher to only log connection info, not set it 3. Removed redundant capability setting (config is sufficient) References: - https://v2.tauri.app/develop/tests/webdriver/example/webdriverio/ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: let xvfb-run handle DISPLAY and support multiremote capabilities Fixed two issues with Tauri testing: 1. Multiremote capabilities handling - onWorkerStart can receive capabilities as an array for multiremote - Changed signature to accept TauriCapabilities | TauriCapabilities[] - Made diagnostics gracefully skip if capabilities structure is unexpected - Added better error logging to debug capability structure issues 2. GTK display errors on Linux - REMOVED setting DISPLAY in onWorkerStart - Setting DISPLAY prevents WDIO's xvfb service from wrapping the worker - Logs showed: "shouldRun=false" because DISPLAY was already set - Now xvfb-run properly wraps the worker and sets DISPLAY - tauri-driver inherits DISPLAY from xvfb-wrapped process environment Flow: 1. WDIO autoXvfb wraps worker with: xvfb-run 2. xvfb-run sets DISPLAY=:99 in worker environment 3. onPrepare spawns tauri-driver with {...process.env} 4. tauri-driver inherits DISPLAY and passes it to Tauri app 5. Tauri app successfully connects to X server Error fixed: "Gtk-WARNING: cannot open display: :99" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: extract Tauri binaries to repository root The pre-built Tauri binaries weren't being found on Windows because they were extracted to the wrong location. Problem: - Archive contains: fixtures/tauri-apps/*/src-tauri/target/** - Was extracting to: tauri-apps-Windows/ - Tests looked for: fixtures/tauri-apps/*/src-tauri/target/** - Result: "No Tauri target directory found" → tries to build → fails Solution: - Extract to repository root (path: .) - Files now end up in correct location: fixtures/tauri-apps/*/src-tauri/target/ - Added verification step to check binaries are in the right place This matches how package builds are extracted (they also extract to repo root). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * chore: ensure no duplicate tests run * fix: broken cache key * chore: fix bash error * fix: use `xvfb-run` * chore: start tauri-driver per worker * chore: don't recompile apps * chore: run tests directly without turbo * refactor: rework * chore: streamline, add debug * chore: don't use an icon * chore: fix windows zip handling * chore: update icon * fix: improve Windows timestamp normalization for ZIP archives Enhances the Windows compression step to handle all timestamp properties and provide better error diagnostics: - Normalize all three timestamp properties (LastWriteTime, CreationTime, LastAccessTime) instead of just LastWriteTime - Process both files and directories (not just files) - Add error handling around Compress-Archive with diagnostics to identify files with invalid timestamps if compression fails - Add -ErrorAction SilentlyContinue to prevent errors from inaccessible files during timestamp normalization This fixes the "DateTimeOffset cannot be converted into a Zip file timestamp" error by ensuring all timestamps are within the ZIP format's valid range (1980-2107). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * refactor: update Tauri E2E tests to use execute API pattern - Replace all direct method calls with browser.tauri.execute() pattern - Update assertions to match actual Tauri backend implementation - Replace non-existent test commands with actual implemented commands - Align API usage with Electron service pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: update standalone, window, and multiremote tests for execute API - Update standalone tests to use execute() pattern for all operations - Fix property assertion from 'platform' to 'os' in standalone tests - Remove check for non-existent getWindowBounds method - Fix window test to remove call to non-existent unminimize_window command - Make window bounds tests more robust for headless/CI environments - Update multiremote tests to use execute() for all window and clipboard operations Note: Window manipulation (set_window_bounds, minimize) may fail in headless CI environments due to window manager limitations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * refactor: simplify Tauri tests to focus on API testing Remove redundant tests that were testing Tauri backend functionality rather than our service API: - Delete backend-access.spec.ts (redundant with api.spec.ts) - Delete filesystem.spec.ts (testing Tauri, not our API) - Delete platform.spec.ts (testing Tauri, not our API) - Delete window.spec.ts (testing Tauri + failing in CI) Streamline remaining tests to focus on our execute() API: - Rename commands.spec.ts → api.spec.ts - Simplify standalone/api.spec.ts (remove window/clipboard tests) - Simplify multiremote/basic.spec.ts (remove window/clipboard tests) The test suite now focuses on: 1. Core execute() API functionality 2. Standalone mode support 3. Multiremote mode support 4. Future: Mocking API (when implemented) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * ci: remove window test-type from Tauri E2E workflow Remove 'window' test-type from CI matrix since window.spec.ts was deleted in the test cleanup. This prevents CI from trying to run non-existent tests. Changes: - Remove 'window' from test-type matrix in Linux, Windows, and macOS jobs - Remove test:e2e:tauri:basic:window script from e2e/package.json - Update reusable workflow description to reflect available test types Remaining test types: - standard: Core API tests - multiremote: Multiremote mode tests - standalone: Standalone mode tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * fix: windows path handling in E2E * chore: update spec paths * fix: multiremote issues * chore: reinstate OS-specific artifact names * chore: normalize paths * chore: add execution dupe check * fix: print summary rather than duplicate results * chore: add debug * chore: add rust debug * fix: update write and read file invocation * chore: update e2e app to tauri v2 * fix: windows artifact path issue * chore: enable global * chore: add perms * fix: use __TAURI__.core.invoke * docs: add first pass at PRD for plugin * chore: try passing undefined, copy electron service execution pattern * debug: Add detailed logging to investigate Tauri parameter passing issue - Add debug logging to write_file Rust command to see received parameters - Add debug logging to JavaScript execute function to see sent parameters - Fix test to pass all required parameters (including null for optional) - This will help identify if the issue is in parameter serialization/deserialization * test: skip multiremote and parameter E2Es * debug: show tauri logs always * feat: Implement automatic data directory isolation for Tauri multiremote - Add utility functions to extract instance ID from capabilities args - Generate unique data directories per multiremote instance (browserA, browserB, etc.) - Set XDG_DATA_HOME (Linux) or TAURI_DATA_DIR (Windows) environment variables - Remove manual environment variable configuration from WDIO config - Service automatically handles isolation without user configuration This should resolve SQLite database locking issues on Linux when running multiple Tauri webview instances in multiremote mode. * fix: Correct multiremote capabilities structure handling - Fix onWorkerStart to properly handle multiremote capabilities object structure - Multiremote caps are { browserA: { capabilities: {...} }, browserB: { capabilities: {...} } } - Extract first instance capabilities and detect instance ID correctly - This should now properly trigger data directory isolation for multiremote instances The previous logic was trying to access tauri:options directly on the multiremote object instead of drilling down to the individual instance capabilities. * fix: Move data directory isolation to onPrepare to fix tauri-driver inheritance - Move setupDataDirectoryIsolation() call to onPrepare() before startTauriDriver() - This ensures tauri-driver inherits XDG_DATA_HOME/TAURI_DATA_DIR environment variables - Previously, isolation was set in onWorkerStart() after tauri-driver was already spawned - Now tauri-driver gets the correct environment variables from the start - This should resolve the SQLite database locking issues on Linux The key insight: tauri-driver is spawned in onPrepare, so environment variables must be set before that point, not in onWorkerStart. * feat: Implement separate tauri-driver processes for multiremote instances - Add support for spawning separate tauri-driver processes per multiremote instance - Each instance gets its own tauri-driver with instance-specific environment variables - Use different ports for each instance (4444 + instance number) - Track multiple processes in tauriDriverProcesses Map - Update stopTauriDriver to clean up all instance-specific processes This should resolve the SQLite database locking issue by ensuring each multiremote instance has its own isolated tauri-driver process with separate XDG_DATA_HOME directories. --------- Co-authored-by: Claude <[email protected]>
1 parent be336a3 commit ddd3997

File tree

217 files changed

+31386
-694
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

217 files changed

+31386
-694
lines changed
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
name: Build Tauri Apps
2+
description: 'Builds Tauri test applications and creates shareable artifacts for E2E testing'
3+
4+
on:
5+
workflow_call:
6+
# Make this a reusable workflow, no value needed
7+
# https://docs.github.com/en/actions/using-workflows/reusing-workflows
8+
inputs:
9+
os:
10+
description: 'OS of runner'
11+
required: true
12+
type: string
13+
build-command:
14+
description: 'Build command for Tauri apps (build or build:debug)'
15+
type: string
16+
default: 'build'
17+
outputs:
18+
build_id:
19+
description: 'Unique identifier for this build'
20+
value: ${{ jobs.build-tauri-apps.outputs.build_id }}
21+
build_date:
22+
description: 'Timestamp when the build completed'
23+
value: ${{ jobs.build-tauri-apps.outputs.build_date }}
24+
artifact_size:
25+
description: 'Size of the build artifact in bytes'
26+
value: ${{ jobs.build-tauri-apps.outputs.artifact_size }}
27+
cache_key:
28+
description: 'Cache key used for artifact uploads, can be passed to download actions'
29+
value: ${{ jobs.build-tauri-apps.outputs.cache_key }}
30+
31+
env:
32+
TURBO_TELEMETRY_DISABLED: 1
33+
TURBO_DAEMON: false
34+
35+
jobs:
36+
# This job builds all Tauri test applications for the specified OS
37+
# Unlike package builds, each OS creates its own artifacts since binaries are platform-specific
38+
build-tauri-apps:
39+
name: Build Tauri Apps
40+
runs-on: ${{ inputs.os }}
41+
outputs:
42+
build_id: ${{ steps.build-info.outputs.build_id }}
43+
build_date: ${{ steps.build-info.outputs.build_date }}
44+
artifact_size: ${{ steps.upload-archive.outputs.size || '0' }}
45+
cache_key: ${{ steps.upload-archive.outputs.cache_key }}
46+
steps:
47+
# Standard checkout with SSH key for private repositories
48+
- name: 👷 Checkout Repository
49+
uses: actions/checkout@v5
50+
with:
51+
ssh-key: ${{ secrets.DEPLOY_KEY }}
52+
53+
# Set up Node.js and PNPM using the reusable action
54+
- name: 🛠️ Setup Development Environment
55+
uses: ./.github/workflows/actions/setup-workspace
56+
with:
57+
node-version: '20'
58+
59+
# Install Rust toolchain for Tauri compilation
60+
- name: 🦀 Install Rust Toolchain
61+
uses: dtolnay/rust-toolchain@stable
62+
63+
# Install Tauri dependencies on Linux
64+
- name: 🦀 Install Tauri Dependencies (Linux)
65+
if: runner.os == 'Linux'
66+
shell: bash
67+
run: |
68+
echo "Installing Tauri dependencies for Linux..."
69+
sudo tee -a /etc/apt/sources.list > /dev/null <<EOT
70+
deb http://archive.ubuntu.com/ubuntu jammy main universe
71+
EOT
72+
sudo apt-get update
73+
sudo apt-get install -y \
74+
build-essential \
75+
pkg-config \
76+
libgtk-3-dev \
77+
libwebkit2gtk-4.0-dev \
78+
libwebkit2gtk-4.1-dev \
79+
libappindicator3-dev \
80+
librsvg2-dev \
81+
patchelf \
82+
libglib2.0-dev \
83+
libsoup-2.4-1 \
84+
libsoup2.4-dev \
85+
libjavascriptcoregtk-4.0-dev \
86+
libjavascriptcoregtk-4.1-dev \
87+
libssl-dev \
88+
libasound2-dev \
89+
libx11-dev \
90+
libxext-dev \
91+
libxfixes-dev \
92+
libxrender-dev \
93+
libxrandr-dev \
94+
libxss-dev \
95+
libxtst-dev \
96+
libxcomposite-dev \
97+
libxcursor-dev \
98+
libxdamage-dev \
99+
libxinerama-dev \
100+
libxcb1-dev \
101+
libxcb-shape0-dev \
102+
libxcb-xfixes0-dev \
103+
libxcb-render0-dev \
104+
libxcb-randr0-dev \
105+
libxcb-xinerama0-dev \
106+
libxcb-xkb-dev \
107+
libxcb-image0-dev \
108+
libxcb-util0-dev \
109+
libxcb-icccm4-dev \
110+
libxcb-ewmh-dev \
111+
libxcb-dri2-0-dev
112+
113+
# Generate build information for tracking
114+
- name: 📊 Generate Build Information
115+
id: build-info
116+
shell: bash
117+
run: |
118+
echo "build_id=$(date +%s)-${{ github.run_id }}-${{ runner.os }}" >> $GITHUB_OUTPUT
119+
echo "build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
120+
121+
# Build all Tauri test applications using Turbo
122+
# This creates the binaries in src-tauri/target/release (or debug)
123+
- name: 🏗️ Build All Tauri Apps
124+
run: pnpm exec turbo run ${{ inputs.build-command }} --filter=tauri-*-app --only --parallel
125+
shell: bash
126+
127+
# Upload Tauri app binaries as artifacts
128+
# Each OS uploads its own artifacts since binaries are platform-specific
129+
# Using GitHub Actions cache with ~90 day retention (vs. 1 day for regular artifacts)
130+
- name: 📦 Upload Tauri App Binaries
131+
id: upload-archive
132+
uses: ./.github/workflows/actions/upload-archive
133+
with:
134+
name: tauri-apps-${{ runner.os }}
135+
output: tauri-apps-${{ runner.os }}/artifact.zip
136+
paths: fixtures/tauri-apps/*/src-tauri/target
137+
cache_key_prefix: tauri-apps
138+
retention_days: '90'

0 commit comments

Comments
 (0)