Back to Tamagui

Tamagui Testing Guide

claude.md

1.144.44.4 KB
Original Source

Please read ./CONTRIBUTING.md as well

Note you need to re-build packages (bun run build in the package directory) as you change them, unless you or someone is running a bun run watch at root.

FOR LONG RUNNNING DEBUGGING run bun run watch in the background its faster and rebuilds all packages.

keep commits to one line, add a trailing "Fixes #" if associated with a GH issue, and start with a convential commit style - UNLESS its a change that shouldn't go into the changelog, in those cases you can do things like docs: or site: .

Tamagui Testing Guide

Running Tests

Kitchen Sink Tests

The kitchen-sink package contains the main integration tests for Tamagui components. To run these tests:

  1. Start the web server (in the background):

    bash
    cd code/kitchen-sink
    bun run start:web
    

    To open a specific test case in the browser:

    bash
    open "http://localhost:9000/?test=YourTestCaseName"
    

    Test case names match the file names in code/kitchen-sink/src/usecases/ (e.g., SelectFocusScopeCase).

    To open a component demo:

    bash
    open "http://localhost:9000/?demo=Select"
    

    Demo names match files in code/demos/src/ without the Demo suffix (e.g., Select for SelectDemo.tsx).

  2. Run all web tests with different animation drivers:

    bash
    bun run test:web
    

    This uses run-tests-parallel.ts which first runs default + webkit projects sequentially, then runs all four animated driver projects (css, native, reanimated, motion) in parallel against a single shared dev server.

  3. Run tests with a specific animation driver:

    bash
    # Using env var + playwright --project flag
    cd code/kitchen-sink
    NODE_ENV=test TAMAGUI_TEST_ANIMATION_DRIVER=css npx playwright test --project=animated-css
    
    # Available projects: animated-css, animated-native, animated-reanimated, animated-motion
    
  4. Run a specific test file:

    bash
    # Using playwright directly
    cd code/kitchen-sink
    npx playwright test tests/PopoverFocusScope.test.tsx
    
    # Or with a specific driver
    NODE_ENV=test TAMAGUI_TEST_ANIMATION_DRIVER=css npx playwright test tests/YourTest.animated.test.tsx --project=animated-css
    
  5. Debug tests:

    bash
    bun run test:web:debug
    # or
    npx playwright test --debug
    

Test Structure

Tests are located in code/kitchen-sink/tests/ and follow these naming conventions:

  • ComponentName.test.tsx - Standard tests that run ONCE with the default animation driver
  • ComponentName.animated.test.tsx - Animation-dependent tests that run with ALL animation drivers (css, native, reanimated, motion)

This separation significantly speeds up the test suite since most tests don't need to run 4x across all animation drivers. Only use .animated.test.tsx for tests that specifically verify animation behavior across different drivers.

Writing Tests

When writing tests for focus behavior or component interactions:

  1. Use appropriate wait times for animations and focus changes
  2. Be aware that trapFocus behavior depends on the component's open state
  3. Test both trapped and non-trapped focus scenarios
  4. Consider browser focus behavior when trapFocus is false

Common Issues

  • If tests fail due to timing, add appropriate waitForTimeout calls
  • For focus tests, ensure elements are visible before testing focus state
  • When testing popover/dialog components, wait for animations to complete

Commit Message Conventions

  • Use site: prefix (not fix(site):) for tamagui.dev changes since they don't go in the changelog
  • Use ci: prefix (not fix(ci):) for CI/workflow changes since they don't go in the changelog
  • Keep commit messages to a single line

iOS Development

See docs/using-ios.md for iOS native development and Detox testing tips.

tamagui.dev API Authentication

When making authenticated API calls from the client side in tamagui.dev, always use the authFetch helper:

ts
import { authFetch } from '~/features/api/authFetch'

const response = await authFetch('/api/some-endpoint', {
  method: 'POST',
  body: JSON.stringify({ ... }),
})

Why this matters: Cookies alone are not reliable for auth in production due to cross-origin/SameSite issues. The authFetch helper automatically includes the Authorization header with the user's access token. All payment/subscription endpoints require this.