This document provides an overview of the testing infrastructure for the react-native-sheet library.
┌─────────────────────────────────────────────────────────┐
│ Unit Tests (Jest + @testing-library/react-native) │
│ ✅ 64 tests covering React/JavaScript logic │
│ ✅ ~80% code coverage │
│ ⚡ Fast (~1 second) │
│ 📁 Location: src/__tests__/ │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ E2E Tests (Detox) │
│ ✅ 7/14 tests passing (50%) │
│ ✅ Tests real native behavior │
│ 🐌 Slower (~minutes) │
│ 📁 Location: e2e/ │
└─────────────────────────────────────────────────────────┘
# Run all unit tests
yarn test
# Run unit tests with coverage
yarn test --coverage
# Run E2E tests on iOS
yarn test:e2e:build:ios
yarn test:e2e:ios
# Run E2E tests on Android
yarn test:e2e:build:android
yarn test:e2e:android✅ React Component Logic
- Component rendering and state management
- Props handling and validation
- Callbacks and event handlers
- Context and Provider functionality
- useEffect hooks and lifecycle
✅ API Functions
presentFittedSheet()dismissFittedSheet()presentGlobalFittedSheet()- Named sheets management
- Queue behavior
❌ What They DON'T Test
- Native module behavior
- Actual sheet animations
- Real gesture handling
- Native insets and safe area
- Backdrop rendering
| File | Tests | Description |
|---|---|---|
FittedSheet.test.tsx |
11 | Core component functionality |
SheetProvider.test.tsx |
8 | Provider and context |
NamedSheets.test.tsx |
11 | Named sheets API |
GlobalSheets.test.tsx |
13 | Global sheets API |
EdgeCases.test.tsx |
18 | Edge cases and complex scenarios |
Utils.test.tsx |
3 | Utility functions |
| Total | 64 |
All files: 80.79% statements | 79.1% branches | 73.33% functions
FittedSheet.tsx: 77.61% statements | 76.92% branches | 68.75% functions
GlobalSheetView.tsx: 82.05% statements | 75% branches | 70% functions
PublicSheetView.tsx: 87.09% statements | 91.66% branches | 88.88% functions
# Run all tests
yarn test
# Run in watch mode
yarn test --watch
# Run with coverage
yarn test --coverage
# Run specific test file
yarn test FittedSheet
# Run tests matching pattern
yarn test --testNamePattern="should present"
# Update snapshots
yarn test -u✅ Native Functionality
- Real bottom sheet rendering
- Native animations
- Gesture handling (swipe to dismiss)
- Scroll view integration
- Data passing
- Multiple sheet types (basic, global, named)
- Custom styling and constraints
✅ User Interactions
- Tap actions
- Swipe gestures
- Scrolling
- Open/close cycles
| File | Tests | Passing | Description |
|---|---|---|---|
sheet.test.ts |
4 | 4/4 ✅ | Basic sheet operations |
comprehensive-sheet.test.ts |
10 | 3/10 |
Advanced functionality |
| Total | 14 | 7/14 (50%) |
Passing Tests:
- ✅ Open and close with button
- ✅ Swipe to dismiss
- ✅ Scroll in sheet content
- ✅ Multiple open/close cycles
- ✅ Data passing to sheets
- ✅ Backdrop dismiss by swiping
- ✅ Rapid multiple operations
Work in Progress:
⚠️ Non-dismissable sheets⚠️ Global sheets API⚠️ Named sheets API⚠️ Custom styling⚠️ Min/max height constraints⚠️ Rapid operations with different types
Note: Some tests require UI scroll improvements for off-screen elements.
E2E tests use a dedicated test screen with testIDs:
- Location:
example/src/screens/modal/E2ETestScreen.tsx - Test IDs:
open-sheet-button- Button to open sheetsheet-content- Sheet containersheet-title- Title in sheetclose-sheet-button- Button to closesheet-scroll-view- Scroll view in sheet
# Prerequisites
brew tap wix/brew
brew install applesimutils
# Build and test
yarn test:e2e:build:ios
yarn test:e2e:ios
# Run specific test
detox test e2e/sheet.test.ts --configuration ios.sim.debug# Start emulator
emulator -avd Pixel_3a_API_30_x86
# Build and test
yarn test:e2e:build:android
yarn test:e2e:android
# Run specific test
detox test e2e/sheet.test.ts --configuration android.emu.debugimport { render, waitFor } from '@testing-library/react-native';
import { FittedSheet, SheetProvider } from '../index';
it('should render sheet when shown', async () => {
const TestComponent = () => {
const sheetRef = useRef<FittedSheetRef>(null);
React.useEffect(() => {
sheetRef.current?.show();
}, []);
return (
<SheetProvider>
<FittedSheet ref={sheetRef}>
<Text>Sheet Content</Text>
</FittedSheet>
</SheetProvider>
);
};
const { getByText } = render(<TestComponent />);
await waitFor(() => {
expect(getByText('Sheet Content')).toBeTruthy();
});
});import { device, element, by, expect as detoxExpect, waitFor } from 'detox';
it('should open and close sheet', async () => {
// Open sheet
await element(by.id('open-sheet-button')).tap();
// Verify sheet is visible
await waitFor(element(by.id('sheet-content')))
.toBeVisible()
.withTimeout(2000);
// Close sheet
await element(by.id('close-sheet-button')).tap();
// Verify sheet is hidden
await waitFor(element(by.id('sheet-content')))
.not.toBeVisible()
.withTimeout(2000);
});name: Tests
on: [push, pull_request]
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: yarn install
- run: yarn test --coverage
- uses: codecov/codecov-action@v3
e2e-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: yarn install
- run: brew tap wix/brew && brew install applesimutils
- run: yarn test:e2e:build:ios
- run: yarn test:e2e:ios-
Test behavior, not implementation
// Good ✅ expect(getByText('Sheet Content')).toBeVisible(); // Bad ❌ expect(component.state.isVisible).toBe(true);
-
Use waitFor for async operations
await waitFor(() => { expect(getByText('Content')).toBeTruthy(); });
-
Clean up after tests
beforeEach(() => { dismissFittedSheetsAll(); });
-
Always use testID for elements
<TouchableOpacity testID="my-button">
-
Use waitFor for animations
await waitFor(element(by.id('sheet'))) .toBeVisible() .withTimeout(2000);
-
Reset state between tests
beforeEach(async () => { await device.reloadReactNative(); });
Tests are slow:
- Use
--maxWorkers=50%to limit CPU usage - Run only changed tests with
--onlyChanged
Coverage not accurate:
- Check
jest.config.jscollectCoverageFrom patterns - Ensure all source files are included
iOS build fails:
cd example/ios
pod install
xcodebuild cleanAndroid emulator issues:
# Cold boot emulator
emulator -avd Pixel_3a_API_30_x86 -no-snapshot-loadTests are flaky:
- Increase timeout values
- Add more waitFor calls
- Check if animations are interfering
- Unit Tests README - Detailed unit test documentation
- E2E Tests README - E2E setup and usage guide
- Detox Documentation - Official Detox docs
- Add tests for iOS-specific behavior
- Add tests for Android-specific behavior
- Increase coverage to 90%+
- Keyboard handling tests
- Dynamic snap points tests
- Multiple sheets stacking tests
- Queue behavior tests
- Global sheet API tests
- Backdrop interaction tests
- Prevent dismiss behavior tests
When adding new features, please:
- Write unit tests for JavaScript logic
- Add E2E tests for user-facing behavior
- Update this documentation
- Ensure all tests pass before submitting PR
# Before committing
yarn test
yarn typecheck
yarn lint