Skip to content

Ziinc/tauri-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TauriTest

A UI integration testing library for Tauri, that exposes Tauri commands to JSdom via N-API bridge, allowing full JS-driven integration testing against application UI and Rust source code.

Getting Started

In your Tauri app crate, add tauri-test:

[lib]
crate-type = ["cdylib", "rlib", "staticlib"]

[build-dependencies]
napi-build = "2"

[dependencies]
tauri = { version = "2", features = [] }
tauri-test = "0.1.0"
napi = { version = "2", default-features = false, features = ["napi8", "async", "serde-json"] }
napi-derive = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

Use napi_build::setup() in build.rs:

fn main() {
    napi_build::setup();
    tauri_build::build();
}

Tauri commands will automatically get invoke(...):

// optionally declare init function to define application state for invoke commands
#[tauri_test::setup(init = init_test_state)]
pub struct App;

// optional
fn init_test_state() -> TodoDb {
    // initialize rust app state
    TodoDb::new()
}

#[tauri::command]
fn greet(name: String) -> String {
    format!("Hello, {name}! You've been greeted from Rust!")
}

Build the src-tauri library to generate the addon loader:

{
  "devDependencies": {
    "vitest": "^3.0.0",
    "@testing-library/react": "^16.0.0",
    "@testing-library/jest-dom": "^6.0.0",
    "jsdom": "^26.0.0"
  },
  "scripts": {
    "pretest": "cd src-tauri && cargo build --lib",
    "test": "vitest run"
  }
}

In tests/setup.ts, load the compiled addon and register a Vitest mock for @tauri-apps/api/core:

import { createRequire } from "node:module";
import { vi } from "vitest";

const require = createRequire(import.meta.url);
const tauriTest = require("../src-tauri/target");

vi.mock("@tauri-apps/api/core", () => ({
  invoke: tauriTest.invoke
}));

Write a real integration test:

import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "../src/App";

it("greets through real Rust", async () => {
  render(<App />);

  await userEvent.type(screen.getByPlaceholderText("Enter a name..."), "World");
  await userEvent.click(screen.getByRole("button", { name: /greet/i }));

  await waitFor(() => {
    expect(screen.getByText(/hello from rust/i)).toBeInTheDocument();
  });
});

About

UI integration testing for Tauri

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors