Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tailor-platform/app-shell/llms.txt

Use this file to discover all available pages before exploring further.

AppShell uses Vitest for fast, modern testing with excellent TypeScript support and React component testing.

Test Framework

The core package uses:
  • Vitest: Fast unit test runner (compatible with Jest API)
  • @testing-library/react: React component testing utilities
  • happy-dom: Lightweight DOM implementation for tests

Running Tests

Run All Tests

From the repository root:
pnpm test
This runs tests across all packages using Turborepo.

Run Core Package Tests

To run tests specifically in the core package:
cd packages/core
pnpm test

Watch Mode

Run tests in watch mode during development:
cd packages/core
pnpm test --watch

Run Specific Test Files

cd packages/core
pnpm test src/components/appshell.test.tsx

Test Configuration

The test setup is defined in packages/core/vitest.config.ts:
import { defineConfig } from "vitest/config";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [tsconfigPaths()],
  test: {
    environment: "happy-dom",
  },
});
Key Configuration:
  • environment: “happy-dom”: Provides a lightweight DOM for component testing
  • tsconfigPaths: Resolves TypeScript path aliases from tsconfig.json

Writing Tests

Component Tests

Use React Testing Library to test components:
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { MyComponent } from './my-component';

describe('MyComponent', () => {
  it('renders correctly', () => {
    render(<MyComponent title="Test" />);
    expect(screen.getByText('Test')).toBeInTheDocument();
  });
});

Hook Tests

Test custom hooks with @testing-library/react:
import { renderHook } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { useMyHook } from './use-my-hook';

describe('useMyHook', () => {
  it('returns expected value', () => {
    const { result } = renderHook(() => useMyHook());
    expect(result.current).toBeDefined();
  });
});

Testing with Context

Wrap components with required providers:
import { render } from '@testing-library/react';
import { AppShellProvider } from '../contexts/appshell-provider';

function renderWithProviders(ui: React.ReactElement) {
  return render(
    <AppShellProvider value={mockContext}>
      {ui}
    </AppShellProvider>
  );
}

describe('ComponentWithContext', () => {
  it('uses context correctly', () => {
    renderWithProviders(<ComponentWithContext />);
    // assertions
  });
});

Test Organization

File Naming

Place test files next to the code they test:
src/
├── components/
│   ├── appshell.tsx
│   ├── appshell.test.tsx      # Component test
│   ├── sidebar-layout.tsx
│   └── sidebar-layout.test.tsx
├── hooks/
│   ├── use-toast.ts
│   └── use-toast.test.ts       # Hook test
└── lib/
    ├── utils.ts
    └── utils.test.ts            # Utility test

Test Structure

Organize tests using describe blocks:
describe('ComponentName', () => {
  describe('rendering', () => {
    it('renders with default props', () => { });
    it('renders with custom props', () => { });
  });

  describe('interactions', () => {
    it('handles click events', () => { });
    it('handles keyboard navigation', () => { });
  });

  describe('edge cases', () => {
    it('handles missing data gracefully', () => { });
  });
});

Code Quality

Type Checking

Run TypeScript type checking:
pnpm type-check
This runs across all packages and ensures type safety.

Linting

Lint the core package:
cd packages/core
pnpm lint

Test Coverage

Generate coverage reports:
cd packages/core
pnpm test --coverage
This creates a coverage report showing tested vs untested code.

Continuous Integration

Tests run automatically on:
  • Pull requests to main
  • Before publishing packages
  • As part of the release process
Ensure all tests pass before submitting a PR.

Best Practices

1

Test user behavior, not implementation

Focus on testing what users see and interact with, not internal component state or implementation details.
2

Use meaningful test descriptions

Write clear describe and it statements that explain what is being tested.
3

Keep tests isolated

Each test should be independent and not rely on the state from other tests.
4

Mock external dependencies

Use Vitest’s mocking capabilities to isolate components from external APIs or services.
5

Test accessibility

Use Testing Library’s accessibility queries (getByRole, getByLabelText) to ensure components are accessible.

Debugging Tests

Run in UI Mode

Vitest provides an interactive UI for debugging:
cd packages/core
pnpm test --ui

Use Console Logs

Debug component output:
import { render, screen } from '@testing-library/react';
import { debug } from '@testing-library/react';

it('debugs component', () => {
  const { container } = render(<MyComponent />);
  screen.debug(); // Prints DOM to console
});

VS Code Debugging

Add a .vscode/launch.json configuration:
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Vitest",
      "runtimeExecutable": "pnpm",
      "runtimeArgs": ["test"],
      "cwd": "${workspaceFolder}/packages/core"
    }
  ]
}

Build docs developers (and LLMs) love