agentic-team-templates 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +280 -0
  2. package/bin/cli.js +5 -0
  3. package/package.json +47 -0
  4. package/src/index.js +521 -0
  5. package/templates/_shared/code-quality.md +162 -0
  6. package/templates/_shared/communication.md +114 -0
  7. package/templates/_shared/core-principles.md +62 -0
  8. package/templates/_shared/git-workflow.md +165 -0
  9. package/templates/_shared/security-fundamentals.md +173 -0
  10. package/templates/blockchain/.cursorrules/defi-patterns.md +520 -0
  11. package/templates/blockchain/.cursorrules/gas-optimization.md +339 -0
  12. package/templates/blockchain/.cursorrules/overview.md +130 -0
  13. package/templates/blockchain/.cursorrules/security.md +318 -0
  14. package/templates/blockchain/.cursorrules/smart-contracts.md +364 -0
  15. package/templates/blockchain/.cursorrules/testing.md +415 -0
  16. package/templates/blockchain/.cursorrules/web3-integration.md +538 -0
  17. package/templates/blockchain/CLAUDE.md +389 -0
  18. package/templates/cli-tools/.cursorrules/architecture.md +412 -0
  19. package/templates/cli-tools/.cursorrules/arguments.md +406 -0
  20. package/templates/cli-tools/.cursorrules/distribution.md +546 -0
  21. package/templates/cli-tools/.cursorrules/error-handling.md +455 -0
  22. package/templates/cli-tools/.cursorrules/overview.md +136 -0
  23. package/templates/cli-tools/.cursorrules/testing.md +537 -0
  24. package/templates/cli-tools/.cursorrules/user-experience.md +545 -0
  25. package/templates/cli-tools/CLAUDE.md +356 -0
  26. package/templates/data-engineering/.cursorrules/data-modeling.md +367 -0
  27. package/templates/data-engineering/.cursorrules/data-quality.md +455 -0
  28. package/templates/data-engineering/.cursorrules/overview.md +85 -0
  29. package/templates/data-engineering/.cursorrules/performance.md +339 -0
  30. package/templates/data-engineering/.cursorrules/pipeline-design.md +280 -0
  31. package/templates/data-engineering/.cursorrules/security.md +460 -0
  32. package/templates/data-engineering/.cursorrules/testing.md +452 -0
  33. package/templates/data-engineering/CLAUDE.md +974 -0
  34. package/templates/devops-sre/.cursorrules/capacity-planning.md +653 -0
  35. package/templates/devops-sre/.cursorrules/change-management.md +584 -0
  36. package/templates/devops-sre/.cursorrules/chaos-engineering.md +651 -0
  37. package/templates/devops-sre/.cursorrules/disaster-recovery.md +641 -0
  38. package/templates/devops-sre/.cursorrules/incident-management.md +565 -0
  39. package/templates/devops-sre/.cursorrules/observability.md +714 -0
  40. package/templates/devops-sre/.cursorrules/overview.md +230 -0
  41. package/templates/devops-sre/.cursorrules/postmortems.md +588 -0
  42. package/templates/devops-sre/.cursorrules/runbooks.md +760 -0
  43. package/templates/devops-sre/.cursorrules/slo-sli.md +617 -0
  44. package/templates/devops-sre/.cursorrules/toil-reduction.md +567 -0
  45. package/templates/devops-sre/CLAUDE.md +1007 -0
  46. package/templates/documentation/.cursorrules/adr.md +277 -0
  47. package/templates/documentation/.cursorrules/api-documentation.md +411 -0
  48. package/templates/documentation/.cursorrules/code-comments.md +253 -0
  49. package/templates/documentation/.cursorrules/maintenance.md +260 -0
  50. package/templates/documentation/.cursorrules/overview.md +82 -0
  51. package/templates/documentation/.cursorrules/readme-standards.md +306 -0
  52. package/templates/documentation/CLAUDE.md +120 -0
  53. package/templates/fullstack/.cursorrules/api-contracts.md +331 -0
  54. package/templates/fullstack/.cursorrules/architecture.md +298 -0
  55. package/templates/fullstack/.cursorrules/overview.md +109 -0
  56. package/templates/fullstack/.cursorrules/shared-types.md +348 -0
  57. package/templates/fullstack/.cursorrules/testing.md +386 -0
  58. package/templates/fullstack/CLAUDE.md +349 -0
  59. package/templates/ml-ai/.cursorrules/data-engineering.md +483 -0
  60. package/templates/ml-ai/.cursorrules/deployment.md +601 -0
  61. package/templates/ml-ai/.cursorrules/model-development.md +538 -0
  62. package/templates/ml-ai/.cursorrules/monitoring.md +658 -0
  63. package/templates/ml-ai/.cursorrules/overview.md +131 -0
  64. package/templates/ml-ai/.cursorrules/security.md +637 -0
  65. package/templates/ml-ai/.cursorrules/testing.md +678 -0
  66. package/templates/ml-ai/CLAUDE.md +1136 -0
  67. package/templates/mobile/.cursorrules/navigation.md +246 -0
  68. package/templates/mobile/.cursorrules/offline-first.md +302 -0
  69. package/templates/mobile/.cursorrules/overview.md +71 -0
  70. package/templates/mobile/.cursorrules/performance.md +345 -0
  71. package/templates/mobile/.cursorrules/testing.md +339 -0
  72. package/templates/mobile/CLAUDE.md +233 -0
  73. package/templates/platform-engineering/.cursorrules/ci-cd.md +778 -0
  74. package/templates/platform-engineering/.cursorrules/developer-experience.md +632 -0
  75. package/templates/platform-engineering/.cursorrules/infrastructure-as-code.md +600 -0
  76. package/templates/platform-engineering/.cursorrules/kubernetes.md +710 -0
  77. package/templates/platform-engineering/.cursorrules/observability.md +747 -0
  78. package/templates/platform-engineering/.cursorrules/overview.md +215 -0
  79. package/templates/platform-engineering/.cursorrules/security.md +855 -0
  80. package/templates/platform-engineering/.cursorrules/testing.md +878 -0
  81. package/templates/platform-engineering/CLAUDE.md +850 -0
  82. package/templates/utility-agent/.cursorrules/action-control.md +284 -0
  83. package/templates/utility-agent/.cursorrules/context-management.md +186 -0
  84. package/templates/utility-agent/.cursorrules/hallucination-prevention.md +253 -0
  85. package/templates/utility-agent/.cursorrules/overview.md +78 -0
  86. package/templates/utility-agent/.cursorrules/token-optimization.md +369 -0
  87. package/templates/utility-agent/CLAUDE.md +513 -0
  88. package/templates/web-backend/.cursorrules/api-design.md +255 -0
  89. package/templates/web-backend/.cursorrules/authentication.md +309 -0
  90. package/templates/web-backend/.cursorrules/database-patterns.md +298 -0
  91. package/templates/web-backend/.cursorrules/error-handling.md +366 -0
  92. package/templates/web-backend/.cursorrules/overview.md +69 -0
  93. package/templates/web-backend/.cursorrules/security.md +358 -0
  94. package/templates/web-backend/.cursorrules/testing.md +395 -0
  95. package/templates/web-backend/CLAUDE.md +366 -0
  96. package/templates/web-frontend/.cursorrules/accessibility.md +296 -0
  97. package/templates/web-frontend/.cursorrules/component-patterns.md +204 -0
  98. package/templates/web-frontend/.cursorrules/overview.md +72 -0
  99. package/templates/web-frontend/.cursorrules/performance.md +325 -0
  100. package/templates/web-frontend/.cursorrules/state-management.md +227 -0
  101. package/templates/web-frontend/.cursorrules/styling.md +271 -0
  102. package/templates/web-frontend/.cursorrules/testing.md +311 -0
  103. package/templates/web-frontend/CLAUDE.md +399 -0
@@ -0,0 +1,345 @@
1
+ # Mobile Performance
2
+
3
+ Optimizing mobile app performance for smooth user experience.
4
+
5
+ ## Performance Goals
6
+
7
+ - **60 FPS**: Smooth animations and scrolling
8
+ - **< 3s**: Cold start time
9
+ - **Responsive**: Touch feedback < 100ms
10
+ - **Efficient**: Minimal battery drain
11
+
12
+ ## List Performance
13
+
14
+ ### Virtualization
15
+
16
+ Only render visible items.
17
+
18
+ ```tsx
19
+ // React Native FlatList
20
+ <FlatList
21
+ data={items}
22
+ renderItem={({ item }) => <ItemComponent item={item} />}
23
+ keyExtractor={(item) => item.id}
24
+ // Performance optimizations
25
+ removeClippedSubviews={true}
26
+ maxToRenderPerBatch={10}
27
+ windowSize={5}
28
+ initialNumToRender={10}
29
+ getItemLayout={(data, index) => ({
30
+ length: ITEM_HEIGHT,
31
+ offset: ITEM_HEIGHT * index,
32
+ index,
33
+ })}
34
+ />
35
+ ```
36
+
37
+ ### Optimized List Items
38
+
39
+ ```tsx
40
+ // Memoize list items
41
+ const ItemComponent = memo(({ item }: { item: Item }) => (
42
+ <View style={styles.item}>
43
+ <Text>{item.title}</Text>
44
+ </View>
45
+ ));
46
+
47
+ // Memoize callbacks
48
+ const renderItem = useCallback(
49
+ ({ item }: { item: Item }) => <ItemComponent item={item} />,
50
+ []
51
+ );
52
+
53
+ const keyExtractor = useCallback((item: Item) => item.id, []);
54
+ ```
55
+
56
+ ## Rendering Optimization
57
+
58
+ ### Avoid Unnecessary Re-renders
59
+
60
+ ```tsx
61
+ // Bad: Inline objects cause re-renders
62
+ <View style={{ padding: 10 }}>
63
+
64
+ // Good: Define styles outside
65
+ const styles = StyleSheet.create({
66
+ container: { padding: 10 },
67
+ });
68
+ <View style={styles.container}>
69
+
70
+ // Bad: Inline functions cause re-renders
71
+ <Button onPress={() => handlePress(id)} />
72
+
73
+ // Good: Memoize callbacks
74
+ const handlePressCallback = useCallback(() => handlePress(id), [id]);
75
+ <Button onPress={handlePressCallback} />
76
+ ```
77
+
78
+ ### Memoization
79
+
80
+ ```tsx
81
+ // Memoize expensive components
82
+ const ExpensiveComponent = memo(({ data }) => {
83
+ // Heavy rendering
84
+ });
85
+
86
+ // Memoize computed values
87
+ const sortedData = useMemo(
88
+ () => data.slice().sort((a, b) => a.name.localeCompare(b.name)),
89
+ [data]
90
+ );
91
+
92
+ // Memoize callbacks
93
+ const handleSubmit = useCallback((values) => {
94
+ api.submit(values);
95
+ }, []);
96
+ ```
97
+
98
+ ### Debounce Expensive Operations
99
+
100
+ ```tsx
101
+ // Debounce search input
102
+ const debouncedSearch = useMemo(
103
+ () => debounce((query: string) => {
104
+ performSearch(query);
105
+ }, 300),
106
+ []
107
+ );
108
+
109
+ <TextInput
110
+ onChangeText={(text) => {
111
+ setQuery(text);
112
+ debouncedSearch(text);
113
+ }}
114
+ />
115
+ ```
116
+
117
+ ## Image Optimization
118
+
119
+ ### Proper Sizing
120
+
121
+ ```tsx
122
+ // Specify dimensions
123
+ <Image
124
+ source={{ uri: imageUrl }}
125
+ style={{ width: 100, height: 100 }}
126
+ resizeMode="cover"
127
+ />
128
+
129
+ // Use appropriate image sizes from server
130
+ const getImageUrl = (id: string, size: 'thumb' | 'medium' | 'full') => {
131
+ const dimensions = { thumb: 100, medium: 300, full: 1000 };
132
+ return `${API_URL}/images/${id}?w=${dimensions[size]}`;
133
+ };
134
+ ```
135
+
136
+ ### Caching
137
+
138
+ ```tsx
139
+ // Use FastImage for better caching
140
+ import FastImage from 'react-native-fast-image';
141
+
142
+ <FastImage
143
+ source={{
144
+ uri: imageUrl,
145
+ priority: FastImage.priority.normal,
146
+ cache: FastImage.cacheControl.immutable,
147
+ }}
148
+ style={styles.image}
149
+ />
150
+ ```
151
+
152
+ ### Lazy Loading
153
+
154
+ ```tsx
155
+ // Load images as they come into view
156
+ <FlatList
157
+ data={images}
158
+ renderItem={({ item }) => (
159
+ <FastImage
160
+ source={{ uri: item.url }}
161
+ style={styles.image}
162
+ />
163
+ )}
164
+ // Images outside window won't load
165
+ windowSize={3}
166
+ />
167
+ ```
168
+
169
+ ## Animations
170
+
171
+ ### Use Native Driver
172
+
173
+ ```tsx
174
+ // Animate on native thread
175
+ Animated.timing(animatedValue, {
176
+ toValue: 1,
177
+ duration: 300,
178
+ useNativeDriver: true, // Key for performance
179
+ }).start();
180
+
181
+ // Native driver supports: transform, opacity
182
+ // Does NOT support: width, height, margin, padding, colors
183
+ ```
184
+
185
+ ### Use Reanimated for Complex Animations
186
+
187
+ ```tsx
188
+ import Animated, {
189
+ useSharedValue,
190
+ useAnimatedStyle,
191
+ withSpring,
192
+ } from 'react-native-reanimated';
193
+
194
+ function AnimatedCard() {
195
+ const scale = useSharedValue(1);
196
+
197
+ const animatedStyle = useAnimatedStyle(() => ({
198
+ transform: [{ scale: scale.value }],
199
+ }));
200
+
201
+ const onPressIn = () => {
202
+ scale.value = withSpring(0.95);
203
+ };
204
+
205
+ const onPressOut = () => {
206
+ scale.value = withSpring(1);
207
+ };
208
+
209
+ return (
210
+ <Pressable onPressIn={onPressIn} onPressOut={onPressOut}>
211
+ <Animated.View style={[styles.card, animatedStyle]}>
212
+ {/* Content */}
213
+ </Animated.View>
214
+ </Pressable>
215
+ );
216
+ }
217
+ ```
218
+
219
+ ## Startup Performance
220
+
221
+ ### Defer Non-Critical Work
222
+
223
+ ```tsx
224
+ function App() {
225
+ useEffect(() => {
226
+ // Defer analytics, crash reporting setup
227
+ InteractionManager.runAfterInteractions(() => {
228
+ initializeAnalytics();
229
+ initializeCrashReporting();
230
+ });
231
+ }, []);
232
+ }
233
+ ```
234
+
235
+ ### Lazy Load Screens
236
+
237
+ ```tsx
238
+ const SettingsScreen = lazy(() => import('./screens/SettingsScreen'));
239
+
240
+ function AppNavigator() {
241
+ return (
242
+ <Suspense fallback={<ScreenLoader />}>
243
+ <Stack.Screen name="Settings" component={SettingsScreen} />
244
+ </Suspense>
245
+ );
246
+ }
247
+ ```
248
+
249
+ ## Memory Management
250
+
251
+ ### Avoid Memory Leaks
252
+
253
+ ```tsx
254
+ useEffect(() => {
255
+ const subscription = eventEmitter.addListener('event', handler);
256
+
257
+ // Always cleanup
258
+ return () => subscription.remove();
259
+ }, []);
260
+
261
+ useEffect(() => {
262
+ let isMounted = true;
263
+
264
+ fetchData().then((data) => {
265
+ if (isMounted) { // Check before setting state
266
+ setData(data);
267
+ }
268
+ });
269
+
270
+ return () => {
271
+ isMounted = false;
272
+ };
273
+ }, []);
274
+ ```
275
+
276
+ ### Monitor Memory
277
+
278
+ ```ts
279
+ // React Native Hermes memory usage
280
+ if (global.HermesInternal) {
281
+ const heapInfo = global.HermesInternal.getRuntimeProperties();
282
+ console.log('Heap size:', heapInfo['Heap size']);
283
+ }
284
+ ```
285
+
286
+ ## Profiling
287
+
288
+ ### React DevTools Profiler
289
+
290
+ 1. Enable profiler in React DevTools
291
+ 2. Record interaction
292
+ 3. Analyze component render times
293
+ 4. Identify unnecessary re-renders
294
+
295
+ ### Performance Monitor
296
+
297
+ ```ts
298
+ // Enable performance monitor in dev
299
+ import { PerformanceMonitor } from 'react-native';
300
+
301
+ // Shows JS/UI frame rates
302
+ PerformanceMonitor.enable();
303
+ ```
304
+
305
+ ### Systrace (Android)
306
+
307
+ ```bash
308
+ # Capture trace
309
+ npx react-native profile-hermes
310
+
311
+ # Analyze in Chrome DevTools
312
+ ```
313
+
314
+ ## Common Issues
315
+
316
+ ### JS Thread Blocking
317
+
318
+ ```tsx
319
+ // Bad: Heavy computation on JS thread
320
+ const processedData = heavyComputation(data);
321
+
322
+ // Good: Move to background/worker
323
+ useEffect(() => {
324
+ InteractionManager.runAfterInteractions(async () => {
325
+ const result = await heavyComputation(data);
326
+ setProcessedData(result);
327
+ });
328
+ }, [data]);
329
+ ```
330
+
331
+ ### Too Many Bridge Calls
332
+
333
+ ```tsx
334
+ // Bad: Multiple small updates
335
+ items.forEach((item, i) => {
336
+ Animated.timing(positions[i], { toValue: i * 10 }).start();
337
+ });
338
+
339
+ // Good: Batch updates
340
+ Animated.parallel(
341
+ items.map((item, i) =>
342
+ Animated.timing(positions[i], { toValue: i * 10 })
343
+ )
344
+ ).start();
345
+ ```
@@ -0,0 +1,339 @@
1
+ # Mobile Testing
2
+
3
+ Testing strategies for mobile applications.
4
+
5
+ ## Testing Pyramid
6
+
7
+ ```
8
+ ╱╲ Device/E2E Tests (few, slow)
9
+ ╱──╲ Integration Tests
10
+ ╱────╲ Component Tests
11
+ ╱──────╲ Unit Tests (many, fast)
12
+ ```
13
+
14
+ ## Unit Tests
15
+
16
+ Test pure functions and business logic.
17
+
18
+ ```ts
19
+ // utils/formatters.test.ts
20
+ import { formatCurrency, formatDate } from './formatters';
21
+
22
+ describe('formatCurrency', () => {
23
+ it('formats USD correctly', () => {
24
+ expect(formatCurrency(1234.56, 'USD')).toBe('$1,234.56');
25
+ });
26
+
27
+ it('handles zero', () => {
28
+ expect(formatCurrency(0, 'USD')).toBe('$0.00');
29
+ });
30
+ });
31
+
32
+ // hooks/useCart.test.ts
33
+ import { renderHook, act } from '@testing-library/react-hooks';
34
+ import { useCart } from './useCart';
35
+
36
+ describe('useCart', () => {
37
+ it('adds item to cart', () => {
38
+ const { result } = renderHook(() => useCart());
39
+
40
+ act(() => {
41
+ result.current.addItem({ id: '1', name: 'Product', price: 10 });
42
+ });
43
+
44
+ expect(result.current.items).toHaveLength(1);
45
+ expect(result.current.total).toBe(10);
46
+ });
47
+ });
48
+ ```
49
+
50
+ ## Component Tests
51
+
52
+ Test components in isolation.
53
+
54
+ ```tsx
55
+ // components/Button.test.tsx
56
+ import { render, fireEvent } from '@testing-library/react-native';
57
+ import { Button } from './Button';
58
+
59
+ describe('Button', () => {
60
+ it('renders label correctly', () => {
61
+ const { getByText } = render(<Button label="Submit" onPress={() => {}} />);
62
+ expect(getByText('Submit')).toBeTruthy();
63
+ });
64
+
65
+ it('calls onPress when pressed', () => {
66
+ const onPress = jest.fn();
67
+ const { getByText } = render(<Button label="Submit" onPress={onPress} />);
68
+
69
+ fireEvent.press(getByText('Submit'));
70
+
71
+ expect(onPress).toHaveBeenCalledTimes(1);
72
+ });
73
+
74
+ it('is disabled when loading', () => {
75
+ const onPress = jest.fn();
76
+ const { getByText } = render(
77
+ <Button label="Submit" onPress={onPress} loading />
78
+ );
79
+
80
+ fireEvent.press(getByText('Submit'));
81
+
82
+ expect(onPress).not.toHaveBeenCalled();
83
+ });
84
+ });
85
+ ```
86
+
87
+ ### Testing with Async Operations
88
+
89
+ ```tsx
90
+ // screens/UserProfile.test.tsx
91
+ import { render, waitFor } from '@testing-library/react-native';
92
+ import { UserProfile } from './UserProfile';
93
+
94
+ jest.mock('../services/api');
95
+
96
+ describe('UserProfile', () => {
97
+ it('displays user data after loading', async () => {
98
+ api.getUser.mockResolvedValue({
99
+ id: '1',
100
+ name: 'John Doe',
101
+ email: 'john@example.com',
102
+ });
103
+
104
+ const { getByText, queryByTestId } = render(<UserProfile userId="1" />);
105
+
106
+ // Loading state
107
+ expect(queryByTestId('loading')).toBeTruthy();
108
+
109
+ // Data loaded
110
+ await waitFor(() => {
111
+ expect(getByText('John Doe')).toBeTruthy();
112
+ expect(getByText('john@example.com')).toBeTruthy();
113
+ });
114
+ });
115
+
116
+ it('shows error on failure', async () => {
117
+ api.getUser.mockRejectedValue(new Error('Network error'));
118
+
119
+ const { getByText } = render(<UserProfile userId="1" />);
120
+
121
+ await waitFor(() => {
122
+ expect(getByText(/error/i)).toBeTruthy();
123
+ });
124
+ });
125
+ });
126
+ ```
127
+
128
+ ## Integration Tests
129
+
130
+ Test navigation and screen interactions.
131
+
132
+ ```tsx
133
+ // navigation/AuthFlow.test.tsx
134
+ import { render, fireEvent, waitFor } from '@testing-library/react-native';
135
+ import { NavigationContainer } from '@react-navigation/native';
136
+ import { AuthNavigator } from './AuthNavigator';
137
+
138
+ const renderWithNavigation = (component: React.ReactElement) => {
139
+ return render(
140
+ <NavigationContainer>{component}</NavigationContainer>
141
+ );
142
+ };
143
+
144
+ describe('Auth Flow', () => {
145
+ it('navigates from login to signup', () => {
146
+ const { getByText } = renderWithNavigation(<AuthNavigator />);
147
+
148
+ fireEvent.press(getByText("Don't have an account? Sign up"));
149
+
150
+ expect(getByText('Create Account')).toBeTruthy();
151
+ });
152
+
153
+ it('logs in and navigates to home', async () => {
154
+ api.login.mockResolvedValue({ token: 'abc', user: { id: '1' } });
155
+
156
+ const { getByPlaceholderText, getByText } = renderWithNavigation(
157
+ <AuthNavigator />
158
+ );
159
+
160
+ fireEvent.changeText(getByPlaceholderText('Email'), 'test@example.com');
161
+ fireEvent.changeText(getByPlaceholderText('Password'), 'password123');
162
+ fireEvent.press(getByText('Log In'));
163
+
164
+ await waitFor(() => {
165
+ expect(getByText('Welcome')).toBeTruthy(); // Home screen
166
+ });
167
+ });
168
+ });
169
+ ```
170
+
171
+ ## E2E Tests (Detox)
172
+
173
+ Test full app on device/simulator.
174
+
175
+ ```ts
176
+ // e2e/login.e2e.ts
177
+ describe('Login Flow', () => {
178
+ beforeAll(async () => {
179
+ await device.launchApp();
180
+ });
181
+
182
+ beforeEach(async () => {
183
+ await device.reloadReactNative();
184
+ });
185
+
186
+ it('should login successfully', async () => {
187
+ await element(by.id('email-input')).typeText('test@example.com');
188
+ await element(by.id('password-input')).typeText('password123');
189
+ await element(by.id('login-button')).tap();
190
+
191
+ await expect(element(by.id('home-screen'))).toBeVisible();
192
+ });
193
+
194
+ it('should show error for invalid credentials', async () => {
195
+ await element(by.id('email-input')).typeText('wrong@example.com');
196
+ await element(by.id('password-input')).typeText('wrongpassword');
197
+ await element(by.id('login-button')).tap();
198
+
199
+ await expect(element(by.text('Invalid credentials'))).toBeVisible();
200
+ });
201
+ });
202
+ ```
203
+
204
+ ### Detox Best Practices
205
+
206
+ ```ts
207
+ // Use testID for reliable selectors
208
+ <TouchableOpacity testID="submit-button" onPress={onSubmit}>
209
+ <Text>Submit</Text>
210
+ </TouchableOpacity>
211
+
212
+ // Wait for elements properly
213
+ await waitFor(element(by.id('list-item-0')))
214
+ .toBeVisible()
215
+ .withTimeout(5000);
216
+
217
+ // Handle animations
218
+ await element(by.id('button')).tap();
219
+ await waitFor(element(by.id('modal'))).toBeVisible();
220
+
221
+ // Scroll to elements
222
+ await element(by.id('scroll-view')).scrollTo('bottom');
223
+ await element(by.id('scroll-view')).scroll(200, 'down');
224
+ ```
225
+
226
+ ## Mocking
227
+
228
+ ### Mock Native Modules
229
+
230
+ ```ts
231
+ // jest.setup.js
232
+ jest.mock('@react-native-async-storage/async-storage', () =>
233
+ require('@react-native-async-storage/async-storage/jest/async-storage-mock')
234
+ );
235
+
236
+ jest.mock('react-native-device-info', () => ({
237
+ getVersion: () => '1.0.0',
238
+ getBuildNumber: () => '1',
239
+ }));
240
+
241
+ jest.mock('@react-native-community/netinfo', () => ({
242
+ addEventListener: jest.fn(() => jest.fn()),
243
+ fetch: jest.fn(() => Promise.resolve({ isConnected: true })),
244
+ }));
245
+ ```
246
+
247
+ ### Mock Navigation
248
+
249
+ ```tsx
250
+ const mockNavigate = jest.fn();
251
+
252
+ jest.mock('@react-navigation/native', () => ({
253
+ ...jest.requireActual('@react-navigation/native'),
254
+ useNavigation: () => ({
255
+ navigate: mockNavigate,
256
+ goBack: jest.fn(),
257
+ }),
258
+ }));
259
+ ```
260
+
261
+ ## Snapshot Testing
262
+
263
+ ```tsx
264
+ // Use for complex UI that shouldn't change unintentionally
265
+ describe('ProductCard', () => {
266
+ it('matches snapshot', () => {
267
+ const tree = render(
268
+ <ProductCard
269
+ product={{
270
+ id: '1',
271
+ name: 'Test Product',
272
+ price: 29.99,
273
+ image: 'https://example.com/image.jpg',
274
+ }}
275
+ />
276
+ ).toJSON();
277
+
278
+ expect(tree).toMatchSnapshot();
279
+ });
280
+ });
281
+ ```
282
+
283
+ ## Test Organization
284
+
285
+ ```
286
+ src/
287
+ ├── components/
288
+ │ ├── Button/
289
+ │ │ ├── Button.tsx
290
+ │ │ └── Button.test.tsx
291
+ │ └── ...
292
+ ├── screens/
293
+ │ ├── Home/
294
+ │ │ ├── HomeScreen.tsx
295
+ │ │ └── HomeScreen.test.tsx
296
+ │ └── ...
297
+ ├── hooks/
298
+ │ ├── useAuth.ts
299
+ │ └── useAuth.test.ts
300
+ └── utils/
301
+ ├── formatters.ts
302
+ └── formatters.test.ts
303
+
304
+ e2e/
305
+ ├── login.e2e.ts
306
+ ├── checkout.e2e.ts
307
+ └── helpers/
308
+ └── testUtils.ts
309
+ ```
310
+
311
+ ## CI/CD Testing
312
+
313
+ ```yaml
314
+ # .github/workflows/test.yml
315
+ jobs:
316
+ unit-tests:
317
+ runs-on: ubuntu-latest
318
+ steps:
319
+ - uses: actions/checkout@v3
320
+ - uses: actions/setup-node@v3
321
+ - run: npm ci
322
+ - run: npm test -- --coverage
323
+
324
+ e2e-ios:
325
+ runs-on: macos-latest
326
+ steps:
327
+ - uses: actions/checkout@v3
328
+ - run: npm ci
329
+ - run: detox build --configuration ios.sim.release
330
+ - run: detox test --configuration ios.sim.release
331
+
332
+ e2e-android:
333
+ runs-on: macos-latest
334
+ steps:
335
+ - uses: actions/checkout@v3
336
+ - run: npm ci
337
+ - run: detox build --configuration android.emu.release
338
+ - run: detox test --configuration android.emu.release
339
+ ```