Usage Examples
Practical examples for testing Tauri applications with WebdriverIO.
Basic Usage
Element Interactions
Standard WebDriver element interactions work with Tauri apps:
describe('Tauri App Interactions', () => {
it('should interact with form elements', async () => {
// Find elements by selector
const input = await browser.$('input[name="username"]');
await input.setValue('test_user');
const button = await browser.$('button[type="submit"]');
await button.click();
// Wait for element and check visibility
const result = await browser.$('.result');
await result.waitForDisplayed();
const text = await result.getText();
expect(text).toBe('Success!');
});
it('should handle multiple elements', async () => {
const buttons = await browser.$$('button');
expect(buttons).toHaveLength(5);
// Interact with each button
for (const button of buttons) {
const text = await button.getText();
console.log('Button text:', text);
}
});
it('should navigate and wait', async () => {
// Navigate within the app
const link = await browser.$('a[href="#settings"]');
await link.click();
// Wait for page to load
const settings = await browser.$('.settings-panel');
await settings.waitForDisplayed({ timeout: 5000 });
});
});
Tauri API Access
Execute JavaScript in App Context
Use browser.tauri.execute() to run JavaScript with access to Tauri APIs:
describe('Tauri API Access', () => {
it('should access window location', async () => {
const url = await browser.tauri.execute(() => {
return window.location.href;
});
console.log('Current URL:', url);
});
it('should access Tauri invoke API', async () => {
const result = await browser.tauri.execute(({ core }) => {
return core.invoke('get_config');
});
expect(result).toBeDefined();
});
it('should use async operations', async () => {
const data = await browser.tauri.execute(async ({ core }) => {
const user = await core.invoke('get_user');
const permissions = await core.invoke('get_user_permissions', { userId: user.id });
return { user, permissions };
});
expect(data.user).toBeDefined();
expect(data.permissions).toBeInstanceOf(Array);
});
it('should execute with parameters', async () => {
const username = 'test_user';
const result = await browser.tauri.execute(
(args) => {
return { received: args.username };
},
{ username }
);
expect(result.received).toBe('test_user');
});
it('should handle errors', async () => {
try {
await browser.tauri.execute(() => {
throw new Error('Test error');
});
} catch (error) {
expect(error.message).toContain('Test error');
}
});
});
Mocking Tauri Commands
Mock Backend Commands
Mock Tauri commands to test frontend behavior without backend:
describe('Command Mocking', () => {
it('should mock a simple command', async () => {
// Set up mock
const mock = await browser.tauri.mock('get_app_version');
await mock.mockReturnValue('1.2.3');
// Call the mocked command
const version = await browser.tauri.execute(({ core }) => {
return core.invoke('get_app_version');
});
expect(version).toBe('1.2.3');
});
it('should mock command with arguments', async () => {
const mock = await browser.tauri.mock('get_user');
await mock.mockReturnValue({ id: 1, name: 'John Doe' });
const user = await browser.tauri.execute(({ core }) => {
return core.invoke('get_user', { userId: 123 });
});
expect(user).toEqual({ id: 1, name: 'John Doe' });
});
it('should track mock calls', async () => {
const mock = await browser.tauri.mock('save_data');
await mock.mockReturnValue({ success: true });
// Call the command multiple times
await browser.tauri.execute(({ core }) => {
core.invoke('save_data', { data: 'test1' });
core.invoke('save_data', { data: 'test2' });
});
expect(mock.calls.length).toBeGreaterThanOrEqual(2);
});
it('should mock command with implementation', async () => {
const mock = await browser.tauri.mock('calculate');
await mock.mockImplementation((a, b) => {
return a + b;
});
const result = await browser.tauri.execute(({ core }) => {
return core.invoke('calculate', { a: 5, b: 3 });
});
expect(result).toBe(8);
});
it('should handle errors in mocks', async () => {
const mock = await browser.tauri.mock('risky_operation');
await mock.mockRejectedValue(new Error('Operation failed'));
try {
await browser.tauri.execute(({ core }) => {
return core.invoke('risky_operation');
});
} catch (error) {
expect(error.message).toBe('Operation failed');
}
});
it('should restore mocks after test', async () => {
const mock = await browser.tauri.mock('get_data');
await mock.mockReturnValue({ mocked: true });
// Restore original behavior
await mock.mockRestore();
// Now calls the real command
const result = await browser.tauri.execute(({ core }) => {
return core.invoke('get_data');
});
// Result should be from actual backend
expect(result).toBeDefined();
});
});
Testing Custom Commands
Invoke Custom Tauri Commands
Test commands you've defined in your Tauri backend:
describe('Custom Tauri Commands', () => {
it('should call custom command with simple return', async () => {
const greeting = await browser.tauri.execute(({ core }) => {
return core.invoke('greet', { name: 'Tauri' });
});
expect(greeting).toBe('Hello, Tauri!');
});
it('should call command returning object', async () => {
const config = await browser.tauri.execute(({ core }) => {
return core.invoke('get_config');
});
expect(config).toHaveProperty('version');
expect(config).toHaveProperty('isDev');
});
it('should handle command with file paths', async () => {
const result = await browser.tauri.execute(({ core }) => {
return core.invoke('read_project_file', {
path: './src/main.rs'
});
});
expect(result).toContain('fn main()');
});
it('should handle command timeout', async () => {
try {
await browser.tauri.execute(async ({ core }) => {
// Simulate a slow operation
return core.invoke('slow_operation');
});
} catch (error) {
// Handle timeout
console.log('Command timed out:', error.message);
}
});
});