Skip to content

Commit a178c55

Browse files
chore: update example basic app (#1218)
1 parent 6aaaf78 commit a178c55

File tree

4 files changed

+76
-56
lines changed

4 files changed

+76
-56
lines changed

examples/basic/__tests__/App.test.tsx

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ test('renders correctly', () => {
99
// Idiom: no need to capture render output, as we will use `screen` for queries.
1010
render(<App />);
1111

12-
// Idiom: `getByXxx` is a predicate by itself, but we will use it with `expect().toBeTruthy()`
12+
// Idiom: `getBy*` queries are predicates by themselves, but we will use it with `expect().toBeTruthy()`
1313
// to clarify our intent.
14-
expect(screen.getByText('Sign in to Example App')).toBeTruthy();
14+
expect(
15+
screen.getByRole('header', { name: 'Sign in to Example App' })
16+
).toBeTruthy();
1517
});
1618

1719
/**
@@ -23,30 +25,34 @@ test('User can sign in successully with correct credentials', async () => {
2325
// Idiom: no need to capture render output, as we will use `screen` for queries.
2426
render(<App />);
2527

26-
// Idiom: `getByXxx` is a predicate by itself, but we will use it with `expect().toBeTruthy()` to
27-
// clarify our intent.
28+
// Idiom: `getBy*` queries are predicates by themselves, but we will use it with `expect().toBeTruthy()`
29+
// to clarify our intent.
2830
// Note: `.toBeTruthy()` is the preferred matcher for checking that elements are present.
29-
expect(screen.getByText('Sign in to Example App')).toBeTruthy();
30-
expect(screen.getByText('Username')).toBeTruthy();
31-
expect(screen.getByText('Password')).toBeTruthy();
31+
expect(
32+
screen.getByRole('header', { name: 'Sign in to Example App' })
33+
).toBeTruthy();
3234

33-
// Hint: we can use `getByLabelText` to find our text inputs in accessibility-friendly way.
35+
// Hint: we can use `getByLabelText` to find our text inputs using their labels.
3436
fireEvent.changeText(screen.getByLabelText('Username'), 'admin');
3537
fireEvent.changeText(screen.getByLabelText('Password'), 'admin1');
3638

37-
// Hint: we can use `getByText` to find our button by its text.
38-
fireEvent.press(screen.getByText('Sign In'));
39+
// Hint: we can use `getByRole` to find our button with given text.
40+
fireEvent.press(screen.getByRole('button', { name: 'Sign In' }));
3941

40-
// Idiom: since pressing button triggers async operation we need to use `findBy` query to wait
42+
// Idiom: since pressing button triggers async operation we need to use `findBy*` query to wait
4143
// for the action to complete.
42-
// Hint: subsequent queries do not need to use `findBy`, because they are used after the async action
44+
// Hint: subsequent queries do not need to use `findBy*`, because they are used after the async action
4345
// already finished
44-
expect(await screen.findByText('Welcome admin!')).toBeTruthy();
45-
46-
// Idiom: use `queryByXxx` with `expect().toBeFalsy()` to assess that element is not present.
47-
expect(screen.queryByText('Sign in to Example App')).toBeFalsy();
48-
expect(screen.queryByText('Username')).toBeFalsy();
49-
expect(screen.queryByText('Password')).toBeFalsy();
46+
expect(
47+
await screen.findByRole('header', { name: 'Welcome admin!' })
48+
).toBeTruthy();
49+
50+
// Idiom: use `queryBy*` with `expect().toBeFalsy()` to assess that element is not present.
51+
expect(
52+
screen.queryByRole('header', { name: 'Sign in to Example App' })
53+
).toBeFalsy();
54+
expect(screen.queryByLabelText('Username')).toBeFalsy();
55+
expect(screen.queryByLabelText('Password')).toBeFalsy();
5056
});
5157

5258
/**
@@ -56,30 +62,32 @@ test('User can sign in successully with correct credentials', async () => {
5662
* that is not directly reflected in the UI.
5763
*
5864
* For this reason prefer quries that correspond to things directly observable by the user like:
59-
* `getByText`, `getByLabelText`, `getByPlaceholderText, `getByDisplayValue`, `getByRole`, etc.
65+
* `getByRole`, `getByText`, `getByLabelText`, `getByPlaceholderText, `getByDisplayValue`, etc.
6066
* over `getByTestId` which is not directly observable by the user.
6167
*
6268
* Note: that some times you will have to resort to `getByTestId`, but treat it as a last resort.
6369
*/
6470
test('User will see errors for incorrect credentials', async () => {
6571
render(<App />);
6672

67-
expect(screen.getByText('Sign in to Example App')).toBeTruthy();
68-
expect(screen.getByText('Username')).toBeTruthy();
69-
expect(screen.getByText('Password')).toBeTruthy();
73+
expect(
74+
screen.getByRole('header', { name: 'Sign in to Example App' })
75+
).toBeTruthy();
7076

7177
fireEvent.changeText(screen.getByLabelText('Username'), 'admin');
7278
fireEvent.changeText(screen.getByLabelText('Password'), 'qwerty123');
73-
fireEvent.press(screen.getByText('Sign In'));
79+
fireEvent.press(screen.getByRole('button', { name: 'Sign In' }));
7480

7581
// Hint: you can use custom Jest Native matcher to check text content.
76-
expect(await screen.findByLabelText('Error')).toHaveTextContent(
82+
expect(await screen.findByRole('alert')).toHaveTextContent(
7783
'Incorrect username or password'
7884
);
7985

80-
expect(screen.getByText('Sign in to Example App')).toBeTruthy();
81-
expect(screen.getByText('Username')).toBeTruthy();
82-
expect(screen.getByText('Password')).toBeTruthy();
86+
expect(
87+
screen.getByRole('header', { name: 'Sign in to Example App' })
88+
).toBeTruthy();
89+
expect(screen.getByLabelText('Username')).toBeTruthy();
90+
expect(screen.getByLabelText('Password')).toBeTruthy();
8391
});
8492

8593
/**
@@ -88,23 +96,25 @@ test('User will see errors for incorrect credentials', async () => {
8896
test('User can sign in after incorrect attempt', async () => {
8997
render(<App />);
9098

91-
expect(screen.getByText('Sign in to Example App')).toBeTruthy();
92-
expect(screen.getByText('Username')).toBeTruthy();
93-
expect(screen.getByText('Password')).toBeTruthy();
99+
expect(
100+
screen.getByRole('header', { name: 'Sign in to Example App' })
101+
).toBeTruthy();
94102

95103
fireEvent.changeText(screen.getByLabelText('Username'), 'admin');
96104
fireEvent.changeText(screen.getByLabelText('Password'), 'qwerty123');
97-
fireEvent.press(screen.getByText('Sign In'));
105+
fireEvent.press(screen.getByRole('button', { name: 'Sign In' }));
98106

99-
expect(await screen.findByLabelText('Error')).toHaveTextContent(
107+
expect(await screen.findByRole('alert')).toHaveTextContent(
100108
'Incorrect username or password'
101109
);
102110

103111
fireEvent.changeText(screen.getByLabelText('Password'), 'admin1');
104-
fireEvent.press(screen.getByText('Sign In'));
112+
fireEvent.press(screen.getByRole('button', { name: 'Sign In' }));
105113

106114
expect(await screen.findByText('Welcome admin!')).toBeTruthy();
107-
expect(screen.queryByText('Sign in to Example App')).toBeFalsy();
108-
expect(screen.queryByText('Username')).toBeFalsy();
109-
expect(screen.queryByText('Password')).toBeFalsy();
115+
expect(
116+
screen.queryByRole('header', { name: 'Sign in to Example App' })
117+
).toBeFalsy();
118+
expect(screen.queryByLabelText('Username')).toBeFalsy();
119+
expect(screen.queryByLabelText('Password')).toBeFalsy();
110120
});

examples/basic/components/Home.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ type Props = {
88
export function Home({ user }: Props) {
99
return (
1010
<View style={styles.container}>
11-
<Text style={styles.title}>Welcome {user}!</Text>
11+
<Text accessibilityRole="header" style={styles.title}>
12+
Welcome {user}!
13+
</Text>
1214
</View>
1315
);
1416
}

examples/basic/components/LoginForm.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
View,
55
Text,
66
TextInput,
7-
TouchableOpacity,
7+
Pressable,
88
ActivityIndicator,
99
} from 'react-native';
1010

@@ -34,7 +34,9 @@ export function LoginForm({ onLoginSuccess }: Props) {
3434

3535
return (
3636
<View style={styles.container}>
37-
<Text style={styles.title}>Sign in to Example App</Text>
37+
<Text accessibilityRole="header" style={styles.title}>
38+
Sign in to Example App
39+
</Text>
3840

3941
<Text style={styles.textLabel}>Username</Text>
4042
<TextInput
@@ -55,18 +57,23 @@ export function LoginForm({ onLoginSuccess }: Props) {
5557
/>
5658

5759
{error && (
58-
<Text accessibilityLabel="Error" style={styles.validator}>
60+
<Text accessibilityRole="alert" style={styles.validator}>
5961
{error}
6062
</Text>
6163
)}
6264

63-
<TouchableOpacity onPress={handleSignIn} style={styles.button}>
65+
<Pressable
66+
accessibilityRole="button"
67+
disabled={isLoading}
68+
onPress={handleSignIn}
69+
style={styles.button}
70+
>
6471
{isLoading ? (
6572
<ActivityIndicator color="white" />
6673
) : (
6774
<Text style={styles.buttonText}>Sign In</Text>
6875
)}
69-
</TouchableOpacity>
76+
</Pressable>
7077
</View>
7178
);
7279
}

examples/basic/package.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,26 @@
66
"ios": "expo start --ios",
77
"web": "expo start --web",
88
"eject": "expo eject",
9-
"test": "jest"
9+
"test": "jest",
10+
"typecheck": "tsc --noEmit"
1011
},
1112
"dependencies": {
12-
"expo": "^46.0.0",
13-
"expo-status-bar": "~1.4.0",
14-
"react": "18.0.0",
15-
"react-dom": "18.0.0",
16-
"react-native": "0.69.4",
13+
"expo": "^47.0.0",
14+
"expo-status-bar": "~1.4.2",
15+
"react": "18.1.0",
16+
"react-dom": "18.1.0",
17+
"react-native": "0.70.5",
1718
"react-native-web": "~0.18.7"
1819
},
1920
"devDependencies": {
20-
"@babel/core": "^7.18.6",
21-
"@testing-library/jest-native": "^5.0.0",
22-
"@testing-library/react-native": "^11.0.0",
23-
"@types/react": "~18.0.0",
24-
"@types/react-native": "~0.69.1",
25-
"jest": "^28.0.0",
26-
"react-test-renderer": "18.0.0",
27-
"typescript": "^4.6.3"
21+
"@babel/core": "^7.19.3",
22+
"@testing-library/jest-native": "^5.1.2",
23+
"@testing-library/react-native": "^11.4.0",
24+
"@types/react": "~18.0.24",
25+
"@types/react-native": "~0.70.6",
26+
"jest": "^29.3.0",
27+
"react-test-renderer": "18.1.0",
28+
"typescript": "^4.8.4"
2829
},
2930
"private": true
3031
}

0 commit comments

Comments
 (0)