Skip to content

Feedback: E2E Testing Challenges and Workarounds for macOS Tauri Apps #1

@badvision

Description

@badvision

Title: Feedback: E2E Testing Challenges and Workarounds for macOS Tauri Apps


(Disclosure: I asked Claude to submit this issue after using this project to pull Claude out of the mud trying to unsuccessfully test a Tauri app; Thank you for this project! This is the only part of the ticket written by a human. The rest is Claude. It is highly likely that some of the struggles detailed herein were a result of Claude not seeing the forest through the trees, and it could be aided by additional details in a AGENTS.md or MCP instructions to inform it as needed.)


Summary

We successfully used tauri-webdriver for E2E testing a production Tauri application on macOS. This issue documents challenges we encountered and the workarounds we developed. We hope this feedback helps improve the tool and assists other users.

Environment

  • OS: macOS (Apple Silicon)
  • Tauri: v1.x
  • WebDriverIO: 9.x
  • Frontend: React 18 + Vite
  • tauri-webdriver: 0.1.3
  • Application: Photo organizer desktop app with native folder picker, database, content-addressable storage

Challenges Encountered

1. Page Reload Causes 30-Second Timeouts ⏱️

Symptom:

await browser.url('http://localhost:5173/'); // ❌ Hangs for 30s, then timeout

Impact: Cannot reload page to ensure fresh frontend code between tests.

Workaround:

  • Avoid page reloads entirely
  • Keep single app instance for entire test suite
  • Manage state via application logic rather than page reloads

Question: Is this a known WKWebView navigation limitation?


2. React State Updates Don't Trigger UI Re-renders 🎨

Symptom:

const result = await browser.execute(() => {
  flushSync(() => {
    setImporting(true);        // ✅ State updates
    setProgress(50);           // ✅ State updates
  });
  return { success: true };    // ✅ Returns successfully
});
// But UI still shows old state! ❌

Impact:

  • Cannot verify UI state changes from programmatic triggers
  • Progress indicators don't appear
  • Status messages don't update
  • Must verify backend state (database/files) instead of UI

Workaround:

  • Use native UI interactions (clicks) for flows requiring UI verification
  • Verify backend state for programmatically triggered actions
  • Accept that browser.execute() context doesn't trigger React rendering

Question: Is this a fundamental limitation of WKWebView's execution context vs. React's render cycle?


3. Console Log Capture Causes Timeouts 📋

Symptom:

// ❌ Attempting to capture console.log causes tests to hang
await browser.execute(() => {
  window.__logs = [];
  const orig = console.log;
  console.log = (...args) => {
    window.__logs.push(args);
    orig(...args);
  };
});

Impact: Difficult to debug test failures without browser console output.

Workaround:

  • Skip console log capture entirely
  • Check /tmp/tauri-wd.log for application output
  • Rely on backend logs for debugging

Question: Is there a recommended approach for accessing console logs during tests?


4. Session Initialization Intermittently Fails with "no window" 🪟

Symptom:

WebDriverError: no window when running "window" with method "GET"
Retrying 1/3
Retrying 2/3

Impact: Adds 1-2 seconds to test startup; occasionally causes flaky test runs.

Workaround: WebDriverIO's retry logic handles it, but inconsistent startup is concerning.

Question: Is there a way to detect/wait for window readiness before accepting connections?


5. Native Dialog Handling Requires Test-Mode Workarounds 📂

Symptom: No way to programmatically interact with macOS native folder picker dialog.

Impact: Cannot test complete user flows involving native dialogs.

Workaround:

// Expose test-only function to bypass native dialog
window.__triggerTestImport = (folderPath) => {
  return invoke('import_folder', { folderPath }); // Bypass picker
};

// In test:
await browser.execute((path) => {
  return window.__triggerTestImport(path);
}, '/tmp/test-data');

Question: Is this the recommended pattern? Should this be documented in examples?


6. Application stderr Not Captured 🔍

Symptom: Rust eprintln!() debug output not visible in test logs or WebDriver output.

Impact: Backend debugging during tests requires manual log file inspection.

Workaround:

  • Check /tmp/tauri-wd.log separately
  • Use file-based logging for backend debugging

Question: Could tauri-webdriver optionally forward application stderr to test output?


What Works Great ✅

  • Session management: Stable once established
  • Element selection: Standard WebDriver selectors work reliably
  • Command execution: browser.execute() runs and returns values correctly
  • WebDriverIO integration: Works as standard WebDriver endpoint
  • Performance: Fast test execution (5 tests in ~17 seconds)
  • Stability: Once workarounds applied, tests run consistently

Example Working Test Pattern

describe('E2E Tests with tauri-webdriver', () => {
  let browser;

  before(async function() {
    this.timeout(30000);
    browser = await remote({
      hostname: '127.0.0.1',
      port: 4444,
      capabilities: {
        'tauri:options': {
          application: './target/debug/my-app',
        }
      }
    });
    await browser.pause(2000); // Wait for app load
  });

  after(async function() {
    if (browser) await browser.deleteSession();
  });

  // ✅ Test via native UI interactions
  it('should work via UI clicks', async function() {
    const button = await browser.$('button.start');
    await button.click();

    const result = await browser.$('.result');
    await result.waitForExist({ timeout: 5000 });
    expect(await result.getText()).toContain('Complete');
  });

  // ✅ Test backend via programmatic triggers + backend verification
  it('should trigger via window function', async function() {
    const result = await browser.execute((path) => {
      return window.__testHelper(path);
    }, '/tmp/data');

    expect(result.success).toBe(true);

    // Verify via backend (database, files, etc) not UI
    // because UI won't update from execute() context
  });
});

Recommendations for Documentation

  1. Clarify page navigation limitations - Document that browser.url() may timeout
  2. Document execution context limitations - Explain that React re-renders don't trigger from browser.execute()
  3. Provide native dialog patterns - Show recommended approach for testing native dialog flows
  4. Console logging guidance - Recommend approaches for test debugging
  5. Add troubleshooting section - Cover common issues like "no window" retries

Impact on Our Project

We successfully use these tests to:

  • ✅ Catch regressions in import functionality
  • ✅ Verify duplicate detection logic
  • ✅ Test database integration
  • ✅ Validate file system operations
  • ✅ Ensure UI elements render correctly

The workarounds are acceptable and tests are now reliable. The tool provides real value!


Questions for Maintainers

  1. Are the page reload timeouts a known WKWebView limitation?
  2. Is the React render issue fundamental to the execution context architecture?
  3. Should native dialog workarounds be documented as official patterns?
  4. Are there plans to improve application log capture?
  5. Would you accept PRs improving documentation in these areas?

Thank you for creating this tool! It enables E2E testing for Tauri apps on macOS, which was previously very difficult. We hope this feedback helps improve it further.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions