Skip to content

Commit f79fcae

Browse files
authored
chore: add search bar to Example app and use it in e2e tests (#2919)
## Description Added search bar to Example app. It is useful for e2e testing - before we would often scroll very far to get to the test screen we wanted - it took a lot of time. Now, we use the search bar to find the screen quickly. ### Why is hiding the keyboard necessary in `selectTestScreen(screenName)` on Android? This is necessary to make the CI pass. Currently, we're using `default` Android image and `Pixel 2` in the GitHub Runner. `AOSP` keyboard displays a banner that asks for access to contacts. The banner happens to be just in front of the button to the test (first search result) when using `Pixel 2`'s screen resolution. Clicking it instead of the button behind would open a popup asking for permission to contacts. CI then would crash with `Test Failed: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?`. https://github.com/user-attachments/assets/4848bc35-6f4b-4343-a3ac-8ddd242b452e ## Changes - add search bar to example app - add e2e utility function `selectTestScreen(screenName)` - use `selectTestScreen(screenName)` in e2e tests for issue/PR examples ## Test code and steps to reproduce CI ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
1 parent 54acad4 commit f79fcae

18 files changed

Lines changed: 96 additions & 131 deletions

FabricExample/e2e/e2e-utils.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,26 @@
1+
import { device, expect, element, by } from 'detox';
2+
13
export const describeIfiOS = device.getPlatform() === 'ios' ? describe : describe.skip;
4+
5+
export async function selectTestScreen(screenName: string) {
6+
await element(by.id('root-screen-switch-search-bar')).tap();
7+
8+
if (device.getPlatform() === 'android') {
9+
await element(by.label('Search')).tap();
10+
11+
// This is the only way I was able to get the search box text input.
12+
// I don't know why element(by.type('androidx.appcompat.widget.SearchView.SearchAutoComplete'))
13+
// does not work even if it appears in view hierarchy returned by Detox in debug logging mode.
14+
await element(by.text('')).replaceText(screenName);
15+
16+
// Press back to hide the keyboard.
17+
// This is necessary to make sure that search results are not obstructed by the keyboard.
18+
// More details: https://github.com/software-mansion/react-native-screens/pull/2919
19+
await device.pressBack();
20+
} else {
21+
await element(by.type('UISearchBarTextField')).replaceText(screenName);
22+
}
23+
24+
await expect(element(by.id(`root-screen-tests-${screenName}`))).toBeVisible();
25+
await element(by.id(`root-screen-tests-${screenName}`)).tap();
26+
}

FabricExample/e2e/examplesTests/events.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ describe('Events', () => {
5454
await waitFor(element(by.id('root-screen-playground-Events')))
5555
.toBeVisible()
5656
.whileElement(by.id('root-screen-examples-scrollview'))
57-
.scroll(100, 'down', NaN, 0.85);
57+
.scroll(300, 'down', NaN, 0.85);
5858
});
5959

6060
it('should Events playground exist', async () => {

FabricExample/e2e/issuesTests/Test2809.e2e.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { device, expect, element, by } from 'detox';
2-
import { describeIfiOS } from '../e2e-utils';
2+
import { describeIfiOS, selectTestScreen } from '../e2e-utils';
33

44
const expectBackButtonMenuWithTheSameLabel = async (text: string) => {
55
await element(by.text(text)).longPressAndDrag(700, NaN, NaN, element(by.text('VOID')), NaN, NaN, "fast", 0); // open
@@ -45,17 +45,11 @@ const expectInitialPageToExist = async (testName: string, expectToExist: Detox.N
4545

4646
describeIfiOS('Test2809', () => {
4747
beforeAll(async () => {
48-
await device.reloadReactNative();
48+
await device.reloadReactNative();
4949
});
5050

5151
it('Test2809 should exist', async () => {
52-
await waitFor(element(by.id('root-screen-tests-Test2809')))
53-
.toBeVisible()
54-
.whileElement(by.id('root-screen-examples-scrollview'))
55-
.scroll(600, 'down', NaN, 0.85);
56-
57-
await expect(element(by.id('root-screen-tests-Test2809'))).toBeVisible();
58-
await element(by.id('root-screen-tests-Test2809')).tap();
52+
await selectTestScreen('Test2809');
5953
});
6054

6155
describe('backButtonMenuEnabled: true', () => {

FabricExample/e2e/issuesTests/Test2842.e2e.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import { device, expect, element, by } from 'detox';
2-
import { describeIfiOS } from '../e2e-utils';
2+
import { describeIfiOS, selectTestScreen } from '../e2e-utils';
33

44
describeIfiOS('Test2842 - pressables in modal', () => {
55
beforeAll(async () => {
66
await device.reloadReactNative();
77
});
88

99
it('Test2842 should exist', async () => {
10-
await waitFor(element(by.id('root-screen-tests-Test2842')))
11-
.toBeVisible()
12-
.whileElement(by.id('root-screen-examples-scrollview'))
13-
.scroll(600, 'down', NaN, 0.85);
14-
15-
await expect(element(by.id('root-screen-tests-Test2842'))).toBeVisible();
16-
await element(by.id('root-screen-tests-Test2842')).tap();
10+
await selectTestScreen('Test2842');
1711
});
1812

1913
it('Modal should open', async () => {

FabricExample/e2e/issuesTests/Test2877.e2e.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { device, expect, element, by } from 'detox';
2-
import { describeIfiOS } from '../e2e-utils';
2+
import { describeIfiOS, selectTestScreen } from '../e2e-utils';
33

44
// issue fixed only on iOS at the moment
55
describeIfiOS('Test2877', () => {
@@ -8,13 +8,7 @@ describeIfiOS('Test2877', () => {
88
});
99

1010
it('Test2877 should exist', async () => {
11-
await waitFor(element(by.id('root-screen-tests-Test2877')))
12-
.toBeVisible()
13-
.whileElement(by.id('root-screen-examples-scrollview'))
14-
.scroll(600, 'down', NaN, 0.85);
15-
16-
await expect(element(by.id('root-screen-tests-Test2877'))).toBeVisible();
17-
await element(by.id('root-screen-tests-Test2877')).tap();
11+
await selectTestScreen('Test2877');
1812
});
1913

2014
it('formSheet should open without hidden content', async () => {

FabricExample/e2e/issuesTests/Test2926.e2e.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { device, expect, element, by } from 'detox';
2-
import { describeIfiOS } from '../e2e-utils';
2+
import { describeIfiOS, selectTestScreen } from '../e2e-utils';
33

44
// PR related to iOS search bar
55
describeIfiOS('Test2926', () => {
@@ -8,13 +8,7 @@ describeIfiOS('Test2926', () => {
88
});
99

1010
it('Test2926 should exist', async () => {
11-
await waitFor(element(by.id('root-screen-tests-Test2926')))
12-
.toBeVisible()
13-
.whileElement(by.id('root-screen-examples-scrollview'))
14-
.scroll(600, 'down', NaN, 0.85);
15-
16-
await expect(element(by.id('root-screen-tests-Test2926'))).toBeVisible();
17-
await element(by.id('root-screen-tests-Test2926')).tap();
11+
await selectTestScreen('Test2926');
1812
});
1913

2014
it('searchBar should be initially visible', async () => {

FabricExample/e2e/issuesTests/Test432.e2e.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import { device, expect, element, by } from 'detox';
2+
import { selectTestScreen } from '../e2e-utils';
23

34
describe('Test432', () => {
45
beforeAll(async () => {
56
await device.reloadReactNative();
67
});
78

89
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();
10+
await selectTestScreen('Test432');
1611
});
1712

1813
it('headerRight element should be fully visible', async () => {

FabricExample/e2e/issuesTests/Test528.e2e.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { device, expect, element, by } from 'detox';
2-
import { describeIfiOS } from '../e2e-utils';
2+
import { describeIfiOS, selectTestScreen } from '../e2e-utils';
33

44
// Detox currently supports orientation only on iOS
55
describeIfiOS('Test528', () => {
@@ -8,13 +8,7 @@ describeIfiOS('Test528', () => {
88
});
99

1010
it('Test528 should exist', async () => {
11-
await waitFor(element(by.id('root-screen-tests-Test528')))
12-
.toBeVisible()
13-
.whileElement(by.id('root-screen-examples-scrollview'))
14-
.scroll(600, 'down', NaN, 0.85);
15-
16-
await expect(element(by.id('root-screen-tests-Test528'))).toBeVisible();
17-
await element(by.id('root-screen-tests-Test528')).tap();
11+
await selectTestScreen('Test528');
1812
});
1913

2014
it('headerRight button should be visible after orientation change', async () => {

FabricExample/e2e/issuesTests/Test577.e2e.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { device, expect, element, by } from 'detox';
2-
import { describeIfiOS } from '../e2e-utils';
2+
import { describeIfiOS, selectTestScreen } from '../e2e-utils';
33

44
// Detox currently supports orientation only on iOS
55
describeIfiOS('Test577', () => {
@@ -8,13 +8,7 @@ describeIfiOS('Test577', () => {
88
});
99

1010
it('Test577 should exist', async () => {
11-
await waitFor(element(by.id('root-screen-tests-Test577')))
12-
.toBeVisible()
13-
.whileElement(by.id('root-screen-examples-scrollview'))
14-
.scroll(600, 'down', NaN, 0.85);
15-
16-
await expect(element(by.id('root-screen-tests-Test577'))).toBeVisible();
17-
await element(by.id('root-screen-tests-Test577')).tap();
11+
await selectTestScreen('Test577');
1812
});
1913

2014
it('does not display content underneath modal with gesture disabled when attempting to close it', async () => {

FabricExample/e2e/issuesTests/Test593.e2e.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { device, expect, element, by } from 'detox';
2+
import { selectTestScreen } from '../e2e-utils';
23

34
const awaitValidEventBehavior = async () => {
45
await expect(
@@ -63,21 +64,10 @@ const awaitValidEventBehavior = async () => {
6364
describe('Test593', () => {
6465
beforeEach(async () => {
6566
await device.reloadReactNative();
66-
67-
await waitFor(element(by.id('root-screen-tests-Test593')))
68-
.toBeVisible()
69-
.whileElement(by.id('root-screen-examples-scrollview'))
70-
.scroll(600, 'down', NaN, 0.85);
71-
});
72-
73-
it('Test593 should exist', async () => {
74-
await expect(element(by.id('root-screen-tests-Test593'))).toBeVisible();
75-
await element(by.id('root-screen-tests-Test593')).tap();
67+
await selectTestScreen('Test593');
7668
});
7769

7870
it('should run transitionStart & transitionEnd opening events', async () => {
79-
await element(by.id('root-screen-tests-Test593')).tap();
80-
8171
await expect(
8272
element(by.text('1. Status | transitionStart | opening')),
8373
).toExist();
@@ -87,8 +77,6 @@ describe('Test593', () => {
8777
});
8878

8979
it('should go back from screen in nested stack and run opening & closing events in correct order', async () => {
90-
await element(by.id('root-screen-tests-Test593')).tap();
91-
9280
await element(by.id('status-button-go-to-deeper')).tap();
9381
await element(by.id('privacy-button-go-to-another')).tap();
9482

@@ -104,8 +92,6 @@ describe('Test593', () => {
10492
});
10593

10694
it('should use "none" animation, go back from screen in nested stack and run opening & closing events in correct order', async () => {
107-
await element(by.id('root-screen-tests-Test593')).tap();
108-
10995
await element(by.id('Test593-stack-animation-picker')).tap();
11096
await element(by.id('stack-animation-none')).tap();
11197

0 commit comments

Comments
 (0)