Skip to content

Commit ef2ff07

Browse files
kligarskikkafar
andauthored
test(e2e,Fabric): add e2e tests for issue/PR examples 42..528 (#2787)
## Description Check which example screens from issues/PRs can be used in e2e testing for tests `Test42, ..., Test528` and implement them if possible for Fabric. In the future, each non-skipped test will be in a seperate PR. ### Test42 Skipped because we can’t really check what is the orientation of the screen with Detox. ### Test111 Skipped because we can’t test flickering with Detox. ### Test263 Skipped because example differs from the problem mentioned in #263. Even when I recreated the issue, it still occurs. [This comment from the PR](#263 (comment)) explains why it is the case. ### Test349 Skipped because we can’t test autofill with Detox. The test also uses outdated prop name. ### Test364 Skipped because the test uses `tabBarVisible` prop that no longer exists. `react-navigation` documentation suggests other [solution](https://reactnavigation.org/docs/hiding-tabbar-in-screens/) to this problem. ### Test 432 Test created. It checks whether correct squares are fully visible. For some reason, on Android, these squares are not `100%` visible from the start (but I don’t see the problem in manual testing). For the test, `waitingFor` the squares to become `100%` visible works. ### Test 528 Test created but only for iOS because Detox supports changing orientation of the device [only on iOS](https://wix.github.io/Detox/docs/api/device/#devicesetorientationorientation). Test checks if the headerRight button is visible after changing screens/orientation. ## Changes - add `Test432` and `Test528` - add comments for every test screen in `apps/src/tests/index.ts` with the reason for (not) implementing e2e test for it ## Test code and steps to reproduce CI ## Checklist - [x] Ensured that CI passes --------- Co-authored-by: Kacper Kafara <[email protected]>
1 parent 68d099a commit ef2ff07

6 files changed

Lines changed: 161 additions & 20 deletions

File tree

FabricExample/Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ PLATFORMS
9595
DEPENDENCIES
9696
activesupport (>= 6.1.7.5, != 7.1.0)
9797
cocoapods (>= 1.13, != 1.15.1, != 1.15.0)
98+
xcodeproj (< 1.26.0)
9899

99100
RUBY VERSION
100101
ruby 3.2.1p31
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { device, expect, element, by } from 'detox';
2+
3+
describe('Test432', () => {
4+
beforeAll(async () => {
5+
await device.reloadReactNative();
6+
});
7+
8+
it('Test432 should exist', async () => {
9+
await waitFor(element(by.id('root-screen-tests-Test432')))
10+
.toBeVisible()
11+
.whileElement(by.id('root-screen-examples-scrollview'))
12+
.scroll(600, 'down', NaN, 0.85);
13+
14+
await expect(element(by.id('root-screen-tests-Test432'))).toBeVisible();
15+
await element(by.id('root-screen-tests-Test432')).tap();
16+
});
17+
18+
it('headerRight element should be fully visible', async () => {
19+
await expect(element(by.id('home-headerRight'))).toBeVisible(100);
20+
});
21+
22+
it('headerRight elements should toggle and stay fully visible', async () => {
23+
await element(by.id('home-button-go-to-details')).tap();
24+
await expect(element(by.id('details-headerRight-red'))).toBeVisible(100);
25+
26+
await element(by.id('details-button-toggle-subviews')).tap();
27+
// On Android, we need to wait for some elements (e.g. at first, this square is only 25% visible)
28+
waitFor(element(by.id('details-headerRight-green'))).toBeVisible(100);
29+
30+
await element(by.id('details-button-toggle-subviews')).tap();
31+
await expect(element(by.id('details-headerRight-red'))).toBeVisible(100);
32+
33+
if (device.getPlatform() === 'ios') {
34+
await element(by.id('BackButton')).tap();
35+
} else {
36+
await device.pressBack();
37+
}
38+
39+
await expect(element(by.id('home-headerRight'))).toBeVisible(100);
40+
});
41+
42+
it('headerLeft and headerRight elements should toggle and stay fully visible', async () => {
43+
await element(by.id('home-button-go-to-info')).tap();
44+
await expect(element(by.id('info-headerRight-green-1'))).toBeVisible(100);
45+
46+
await element(by.id('info-button-toggle-subviews')).tap();
47+
waitFor(element(by.id('info-headerRight-green-1'))).toBeVisible(100);
48+
waitFor(element(by.id('info-headerRight-green-2'))).toBeVisible(100);
49+
waitFor(element(by.id('info-headerLeft-red'))).toBeVisible(100);
50+
51+
await element(by.id('info-button-toggle-subviews')).tap();
52+
waitFor(element(by.id('info-headerRight-green-1'))).toBeVisible(100);
53+
54+
if (device.getPlatform() === 'ios') {
55+
await element(by.id('BackButton')).tap();
56+
} else {
57+
await device.pressBack();
58+
}
59+
60+
await expect(element(by.id('home-headerRight'))).toBeVisible(100);
61+
});
62+
63+
it('headerRight element on modal should be fully visible', async () => {
64+
await element(by.id('home-button-show-settings')).tap();
65+
await expect(element(by.id('settings-headerRight'))).toBeVisible(100);
66+
67+
if (device.getPlatform() === 'ios') {
68+
await element(by.id('settings-text')).swipe('down', 'fast');
69+
} else {
70+
await device.pressBack();
71+
}
72+
await expect(element(by.id('home-headerRight'))).toBeVisible(100);
73+
});
74+
});
75+
76+
// Detox currently supports orientation only on iOS
77+
if (device.getPlatform() === 'ios') {
78+
describe('Test528', () => {
79+
beforeAll(async () => {
80+
await device.reloadReactNative();
81+
});
82+
83+
it('Test528 should exist', async () => {
84+
await waitFor(element(by.id('root-screen-tests-Test528')))
85+
.toBeVisible()
86+
.whileElement(by.id('root-screen-examples-scrollview'))
87+
.scroll(600, 'down', NaN, 0.85);
88+
89+
await expect(element(by.id('root-screen-tests-Test528'))).toBeVisible();
90+
await element(by.id('root-screen-tests-Test528')).tap();
91+
});
92+
93+
it('headerRight button should be visible after orientation change', async () => {
94+
await expect(element(by.text('Custom Button'))).toBeVisible(100);
95+
await device.setOrientation('landscape');
96+
await expect(element(by.text('Custom Button'))).toBeVisible(100);
97+
await device.setOrientation('portrait');
98+
await expect(element(by.text('Custom Button'))).toBeVisible(100);
99+
});
100+
101+
it('headerRight button should be visible after coming back from horizontal screen', async () => {
102+
await element(by.text('Go to Screen 2')).tap();
103+
await device.setOrientation('landscape');
104+
await element(by.id('BackButton')).tap();
105+
await expect(element(by.text('Custom Button'))).toBeVisible(100);
106+
await device.setOrientation('portrait');
107+
await expect(element(by.text('Custom Button'))).toBeVisible(100);
108+
});
109+
});
110+
}

FabricExample/ios/Podfile.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,7 +1733,7 @@ PODS:
17331733
- ReactCommon/turbomodule/bridging
17341734
- ReactCommon/turbomodule/core
17351735
- Yoga
1736-
- RNScreens (4.10.0-beta.3):
1736+
- RNScreens (4.10.0):
17371737
- DoubleConversion
17381738
- glog
17391739
- hermes-engine
@@ -1754,9 +1754,9 @@ PODS:
17541754
- ReactCodegen
17551755
- ReactCommon/turbomodule/bridging
17561756
- ReactCommon/turbomodule/core
1757-
- RNScreens/common (= 4.10.0-beta.3)
1757+
- RNScreens/common (= 4.10.0)
17581758
- Yoga
1759-
- RNScreens/common (4.10.0-beta.3):
1759+
- RNScreens/common (4.10.0):
17601760
- DoubleConversion
17611761
- glog
17621762
- hermes-engine
@@ -2075,7 +2075,7 @@ SPEC CHECKSUMS:
20752075
ReactCommon: 179964ffc47fa62ad0e1eebac704e88c59b46667
20762076
RNGestureHandler: 4e7defe5095e936424173fc75f0bf2af5bba8e23
20772077
RNReanimated: 183ca222293bd622678e387100e54d03d952c73b
2078-
RNScreens: b40d97d6ad4b6f1f55552bed30b845ae01ff3d2c
2078+
RNScreens: 0f01bbed9bd8045a8d58e4b46993c28c7f498f3c
20792079
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
20802080
Yoga: 330be28eee1242da875db9e851b19a4df496b999
20812081

apps/src/shared/Square.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import { View } from 'react-native';
44
interface Props {
55
color?: string;
66
size?: number;
7+
testID?: string;
78
}
89

910
export const Square = ({
1011
size = 100,
1112
color = 'red',
13+
testID,
1214
}: Props): React.JSX.Element => (
13-
<View style={{ width: size, height: size, backgroundColor: color }} />
15+
<View style={{ width: size, height: size, backgroundColor: color }} testID={testID} />
1416
);

apps/src/tests/Test432.tsx

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,17 @@ const HomeScreen = ({ navigation }: StackScreenProps<'Home'>) => {
2626
<Button
2727
title={'Go to details'}
2828
onPress={() => navigation.navigate('Details')}
29+
testID="home-button-go-to-details"
2930
/>
3031
<Button
3132
title={'Go to info'}
3233
onPress={() => navigation.navigate('Info')}
34+
testID="home-button-go-to-info"
3335
/>
3436
<Button
3537
title={'Show settings'}
3638
onPress={() => navigation.navigate('Settings')}
39+
testID="home-button-show-settings"
3740
/>
3841
</View>
3942
);
@@ -45,29 +48,51 @@ const DetailsScreen = ({ navigation }: StackScreenProps<'Details'>) => {
4548
navigation.setOptions({
4649
headerBackVisible: !x,
4750
headerRight: () =>
48-
x ? <Square size={20} color="green" /> : <Square size={10} />,
51+
x ? (
52+
<Square size={20} color="green" testID="details-headerRight-green" />
53+
) : (
54+
<Square size={10} testID="details-headerRight-red" />
55+
),
4956
});
5057
}, [navigation, x]);
5158

52-
return <Button title="Toggle subviews" onPress={() => setX(prev => !prev)} />;
59+
return (
60+
<Button
61+
title="Toggle subviews"
62+
onPress={() => setX(prev => !prev)}
63+
testID="details-button-toggle-subviews"
64+
/>
65+
);
5366
};
5467

5568
const SettingsScreen = () => {
56-
return <Text>Settings</Text>;
69+
return <Text testID="settings-text">Settings</Text>;
5770
};
5871

5972
const InfoScreen = ({ navigation }: StackScreenProps<'Info'>) => {
6073
const [hasLeftItem, setHasLeftItem] = useState(false);
6174

6275
const square1 = (props: { tintColor?: string }) => (
6376
<View style={{ gap: 8, flexDirection: 'row' }}>
64-
{hasLeftItem && <Square {...props} color="green" size={20} />}
65-
<Square {...props} color="green" size={20} />
77+
{hasLeftItem && (
78+
<Square
79+
{...props}
80+
color="green"
81+
size={20}
82+
testID="info-headerRight-green-2"
83+
/>
84+
)}
85+
<Square
86+
{...props}
87+
color="green"
88+
size={20}
89+
testID="info-headerRight-green-1"
90+
/>
6691
</View>
6792
);
6893

6994
const square2 = (props: { tintColor?: string }) => (
70-
<Square {...props} color="red" size={20} />
95+
<Square {...props} color="red" size={20} testID="info-headerLeft-red" />
7196
);
7297

7398
useLayoutEffect(() => {
@@ -82,6 +107,7 @@ const InfoScreen = ({ navigation }: StackScreenProps<'Info'>) => {
82107
<Button
83108
title="Toggle subviews"
84109
onPress={() => setHasLeftItem(prev => !prev)}
110+
testID="info-button-toggle-subviews"
85111
/>
86112
);
87113
};
@@ -95,7 +121,9 @@ const StackNavigator = () => {
95121
name="Home"
96122
component={HomeScreen}
97123
options={{
98-
headerRight: () => <Square size={20} color="black" />,
124+
headerRight: () => (
125+
<Square size={20} color="black" testID="home-headerRight" />
126+
),
99127
}}
100128
/>
101129
<Stack.Screen name="Details" component={DetailsScreen} />
@@ -112,7 +140,7 @@ const StackNavigator = () => {
112140
options={{
113141
presentation: 'modal',
114142
animation: 'slide_from_bottom',
115-
headerRight: () => <Square size={30} />,
143+
headerRight: () => <Square size={30} testID="settings-headerRight" />,
116144
}}
117145
/>
118146
</Stack.Navigator>

apps/src/tests/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// @ts-nocheck
22

3-
export { default as Test42 } from './Test42';
4-
export { default as Test111 } from './Test111';
5-
export { default as Test263 } from './Test263';
6-
export { default as Test349 } from './Test349';
7-
export { default as Test364 } from './Test364';
8-
export { default as Test432 } from './Test432';
9-
export { default as Test528 } from './Test528';
3+
export { default as Test42 } from './Test42'; // [E2E skipped]: can't check orientation, unclear problem description
4+
export { default as Test111 } from './Test111'; // [E2E skipped]: can't check flickering
5+
export { default as Test263 } from './Test263'; // [E2E skipped]: example differs from PR, even if changed the problem still occurs
6+
export { default as Test349 } from './Test349'; // [E2E skipped]: can't check autofill easily, wrong prop name
7+
export { default as Test364 } from './Test364'; // [E2E skipped]: tabBarVisible prop doesn't exist anymore, suggested solution is to change navigator hierarchy (proposed in PR and in react-navigation docs)
8+
export { default as Test432 } from './Test432'; // [E2E created]
9+
export { default as Test528 } from './Test528'; // [E2E created](iOS): Detox supports changing orientation only on iOS
1010
export { default as Test550 } from './Test550';
1111
export { default as Test556 } from './Test556';
1212
export { default as Test564 } from './Test564';

0 commit comments

Comments
 (0)