Skip to content

Commit b3bdf5b

Browse files
author
greweb
committed
fix(e2e): improve Detox tests with scroll handling and navigation fixes
- Fix device.reloadReactNative() crash by using manual back navigation - Add scroll logic to find capture buttons hidden by RN warnings - Add scroll after capture to see success messages and results - Remove blocking Alert.alert from ImageTestScreen and WebViewTestScreen - Add testID='homeScrollView' to HomeScreen for test navigation - Enable all 10 screen tests with proper navigation and validation
1 parent ce7e825 commit b3bdf5b

File tree

4 files changed

+94
-49
lines changed

4 files changed

+94
-49
lines changed

example/e2e/tests/viewshot-all-screens.test.js

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,36 @@ describe('📸 ViewShot - All Screens', () => {
1818
});
1919
});
2020

21-
beforeEach(async () => {
22-
// Return to home screen between tests
23-
await device.reloadReactNative();
24-
await waitFor(element(by.text('🚀 React Native ViewShot')))
25-
.toBeVisible()
26-
.withTimeout(20000);
27-
});
21+
/**
22+
* Navigate back to home screen
23+
*/
24+
const goBackToHome = async () => {
25+
// Check if we're already on home
26+
try {
27+
await expect(element(by.text('🚀 React Native ViewShot'))).toBeVisible();
28+
console.log('✅ Already on home screen');
29+
return;
30+
} catch {
31+
// Not on home, need to navigate back
32+
}
33+
34+
// Try to navigate back using React Navigation back button
35+
try {
36+
console.log('🔙 Attempting to go back to home...');
37+
// Tap the first Back button (navigation header)
38+
await element(by.label('Back')).atIndex(0).tap();
39+
await new Promise(resolve => setTimeout(resolve, 1000));
40+
41+
// Wait for home screen
42+
await waitFor(element(by.text('🚀 React Native ViewShot')))
43+
.toBeVisible()
44+
.withTimeout(5000);
45+
console.log('✅ Back to home screen');
46+
} catch (e) {
47+
console.log(`⚠️ Failed to go back: ${e.message}`);
48+
// If back fails, the test will fail when trying to find the next screen button
49+
}
50+
};
2851

2952
/**
3053
* Helper to capture a screen with scrolling to see the result
@@ -36,35 +59,81 @@ describe('📸 ViewShot - All Screens', () => {
3659
snapshotName,
3760
scrollViewId,
3861
) => {
62+
// Ensure we're on home screen
63+
await goBackToHome();
64+
65+
// Scroll home screen to make sure the button is visible
66+
try {
67+
await waitFor(element(by.text(screenTitle)))
68+
.toBeVisible()
69+
.withTimeout(2000);
70+
} catch {
71+
// Button not visible, scroll down to find it
72+
for (let i = 0; i < 3; i++) {
73+
try {
74+
await element(by.id('homeScrollView')).swipe('up', 'fast', 0.5);
75+
await new Promise(resolve => setTimeout(resolve, 500));
76+
await expect(element(by.text(screenTitle))).toBeVisible();
77+
break; // Found it
78+
} catch {
79+
// Continue scrolling
80+
}
81+
}
82+
}
83+
3984
// Navigate to screen
40-
await element(by.text(screenTitle)).tap();
85+
console.log(`🔄 Navigating to: ${screenTitle}`);
86+
await element(by.text(screenTitle)).atIndex(0).tap();
87+
await new Promise(resolve => setTimeout(resolve, 2000)); // Wait for navigation
88+
89+
// Scroll down to find the capture button (may be below warnings/content)
90+
console.log(`⏳ Looking for button: ${captureButtonText}`);
91+
if (scrollViewId) {
92+
// Try to find button, scroll if needed
93+
let found = false;
94+
for (let i = 0; i < 3 && !found; i++) {
95+
try {
96+
await expect(element(by.text(captureButtonText))).toBeVisible();
97+
found = true;
98+
console.log(`✅ Button found after ${i} scrolls`);
99+
} catch {
100+
console.log(`⬆️ Scrolling to find button (attempt ${i + 1})...`);
101+
try {
102+
await element(by.id(scrollViewId)).swipe('up', 'slow', 0.5);
103+
await new Promise(resolve => setTimeout(resolve, 500));
104+
} catch {
105+
// ScrollView might not be scrollable
106+
}
107+
}
108+
}
109+
}
41110

42-
// Wait for capture button
111+
// Wait for capture button to be fully visible
43112
await waitFor(element(by.text(captureButtonText)))
44113
.toBeVisible()
45-
.withTimeout(10000);
114+
.withTimeout(5000);
46115

47116
// Tap capture button
48117
await element(by.text(captureButtonText)).tap();
118+
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for capture
49119

50-
// Wait for success indicator
51-
await waitFor(element(by.text(successText)))
52-
.toBeVisible()
53-
.withTimeout(10000);
54-
55-
console.log(`✅ ${snapshotName} captured`);
56-
57-
// Scroll to see full result
120+
// Scroll down twice to see the success message and full result
58121
if (scrollViewId) {
59122
await element(by.id(scrollViewId)).swipe('up', 'slow', 0.75);
60123
await new Promise(resolve => setTimeout(resolve, 800));
61124
await element(by.id(scrollViewId)).swipe('up', 'slow', 0.75);
62125
await new Promise(resolve => setTimeout(resolve, 800));
63-
await element(by.id(scrollViewId)).swipe('up', 'slow', 0.75);
64126
}
65127

128+
// Wait for success indicator
129+
await waitFor(element(by.text(successText)))
130+
.toBeVisible()
131+
.withTimeout(10000);
132+
133+
console.log(`✅ ${snapshotName} captured`);
134+
66135
// Wait for UI to settle
67-
await new Promise(resolve => setTimeout(resolve, 3000));
136+
await new Promise(resolve => setTimeout(resolve, 2000));
68137

69138
// Capture and validate
70139
const result = await snapshotMatcher.captureAndValidate(

example/src/screens/HomeScreen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ const HomeScreen: React.FC<Props> = ({ navigation }) => {
202202
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
203203
backgroundColor={backgroundStyle.backgroundColor}
204204
/>
205-
<ScrollView style={styles.scrollView}>
205+
<ScrollView style={styles.scrollView} testID="homeScrollView">
206206
<View style={styles.header}>
207207
<Text style={styles.title}>🚀 React Native ViewShot</Text>
208208
<Text style={styles.subtitle}>New Architecture Test Suite</Text>

example/src/screens/ImageTestScreen.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ const ImageTestScreen: React.FC = () => {
3030
const uri = `data:image/${captureFormat};base64,${base64}`;
3131
setCapturedUri(uri);
3232
setIsCapturing(false);
33-
Alert.alert(
34-
'Image Captured!',
35-
`Image captured in ${captureFormat.toUpperCase()} format`,
36-
);
3733
},
3834
[captureFormat],
3935
);

example/src/screens/WebViewTestScreen.tsx

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ const WebViewTestScreen: React.FC = () => {
4242

4343
const onCaptureFailure = useCallback((error: Error) => {
4444
setIsCapturing(false);
45-
Alert.alert(
46-
'Capture Failed',
47-
`Error: ${error.message}\n\n⚠️ This is the known iOS bug #577!`,
48-
);
45+
// Alert removed for E2E testing
4946
}, []);
5047

5148
const handleManualCapture = useCallback(() => {
@@ -151,26 +148,9 @@ const WebViewTestScreen: React.FC = () => {
151148
onPress={() => {
152149
const newMode =
153150
captureMode === 'continuous' ? 'manual' : 'continuous';
154-
if (newMode === 'continuous' && Platform.OS === 'ios') {
155-
Alert.alert(
156-
'⚠️ iOS Bug Warning',
157-
'Continuous mode may cause infinite screenshot loop on iOS (Bug #577). Use at your own risk!',
158-
[
159-
{ text: 'Cancel', style: 'cancel' },
160-
{
161-
text: 'Enable Anyway',
162-
style: 'destructive',
163-
onPress: () => {
164-
setCaptureMode('continuous');
165-
setCapturedUri(null);
166-
},
167-
},
168-
],
169-
);
170-
} else {
171-
setCaptureMode(newMode);
172-
setCapturedUri(null);
173-
}
151+
// Alert removed for E2E testing
152+
setCaptureMode(newMode);
153+
setCapturedUri(null);
174154
}}
175155
>
176156
<Text style={styles.toggleText}>

0 commit comments

Comments
 (0)