mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
refactor: update example apps (#1024)
This commit is contained in:
committed by
GitHub
parent
14dba849d7
commit
7dd403b2ea
@@ -1,14 +1,2 @@
|
||||
import 'react-native-gesture-handler/jestSetup';
|
||||
|
||||
jest.mock('react-native-reanimated', () => {
|
||||
const Reanimated = require('react-native-reanimated/mock');
|
||||
|
||||
// The mock for `call` immediately calls the callback which is incorrect
|
||||
// So we override it with a no-op
|
||||
Reanimated.default.call = () => {};
|
||||
|
||||
return Reanimated;
|
||||
});
|
||||
|
||||
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
|
||||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
preset: 'react-native',
|
||||
setupFiles: ['./jest-setup.js'],
|
||||
setupFilesAfterEnv: ['./jest-setup.js'],
|
||||
transformIgnorePatterns: [
|
||||
'node_modules/(?!(jest-)?react-native|@react-native-community|@react-navigation)',
|
||||
'node_modules/(?!(jest-)?react-native|@react-native|@react-native-community|@react-navigation)',
|
||||
],
|
||||
};
|
||||
|
||||
@@ -7,25 +7,20 @@
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-native-community/masked-view": "^0.1.9",
|
||||
"@react-navigation/drawer": "^5.11.4",
|
||||
"@react-navigation/native": "^5.1.6",
|
||||
"@react-navigation/stack": "^5.2.13",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.13.1",
|
||||
"react-native": "^0.62.2",
|
||||
"react-native-gesture-handler": "^1.6.1",
|
||||
"react-native-reanimated": "^1.8.0",
|
||||
"react-native-safe-area-context": "^0.7.3",
|
||||
"react-native-screens": "^2.5.0"
|
||||
"@react-navigation/native": "^6.0.11",
|
||||
"@react-navigation/native-stack": "^6.7.0",
|
||||
"@react-navigation/stack": "^6.2.2",
|
||||
"react": "^18.0.0",
|
||||
"react-native": "^0.69.2",
|
||||
"react-native-safe-area-context": "^4.3.1",
|
||||
"react-native-screens": "^3.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/runtime": "^7.9.2",
|
||||
"babel-jest": "^25.4.0",
|
||||
"jest": "^25.4.0",
|
||||
"metro-react-native-babel-preset": "^0.59.0",
|
||||
"@testing-library/react-native": "^7.0.0-rc.0",
|
||||
"react-test-renderer": "^16.13.1"
|
||||
"@testing-library/react-native": "^11.0.0",
|
||||
"babel-jest": "^28.0.0",
|
||||
"jest": "^28.0.0",
|
||||
"metro-react-native-babel-preset": "^0.70.0",
|
||||
"react-test-renderer": "^18.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import 'react-native-gesture-handler';
|
||||
import React from 'react';
|
||||
import { StatusBar, StyleSheet, View } from 'react-native';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
|
||||
import AppNavigator from './AppNavigator';
|
||||
|
||||
export default function App() {
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import * as React from 'react';
|
||||
import { createStackNavigator } from '@react-navigation/stack';
|
||||
|
||||
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||
import HomeScreen from './screens/HomeScreen';
|
||||
import DetailsScreen from './screens/DetailsScreen';
|
||||
|
||||
const { Screen, Navigator } = createStackNavigator();
|
||||
const Stack = createNativeStackNavigator();
|
||||
|
||||
export default function Navigation() {
|
||||
const options = {};
|
||||
|
||||
return (
|
||||
<Navigator>
|
||||
<Screen name="Home" component={HomeScreen} />
|
||||
<Screen options={options} name="Details" component={DetailsScreen} />
|
||||
</Navigator>
|
||||
<Stack.Navigator>
|
||||
<Stack.Screen name="Home" component={HomeScreen} />
|
||||
<Stack.Screen name="Details" component={DetailsScreen} />
|
||||
</Stack.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as React from 'react';
|
||||
import { screen, fireEvent } from '@testing-library/react-native';
|
||||
import { renderWithNavigation } from './test-utils';
|
||||
import AppNavigator from './AppNavigator';
|
||||
|
||||
test('page contains the header and 10 items', async () => {
|
||||
renderWithNavigation(<AppNavigator />);
|
||||
|
||||
const header = await screen.findByText('List of numbers from 1 to 20');
|
||||
expect(header).toBeTruthy();
|
||||
|
||||
const items = screen.getAllByText(/Item number/);
|
||||
expect(items.length).toBe(10);
|
||||
});
|
||||
|
||||
test('clicking on one item takes you to the details screen', async () => {
|
||||
renderWithNavigation(<AppNavigator />);
|
||||
|
||||
const toClick = await screen.findByText('Item number 5');
|
||||
fireEvent(toClick, 'press');
|
||||
|
||||
expect(screen.getByText('Showing details for 5')).toBeTruthy();
|
||||
expect(screen.getByText('the number you have chosen is 5')).toBeTruthy();
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import 'react-native-gesture-handler';
|
||||
import React from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
|
||||
import DrawerAppNavigator from './DrawerAppNavigator';
|
||||
|
||||
export default function DrawerApp() {
|
||||
return (
|
||||
<NavigationContainer>
|
||||
<DrawerAppNavigator />
|
||||
</NavigationContainer>
|
||||
);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import React from 'react';
|
||||
import {createDrawerNavigator} from '@react-navigation/drawer';
|
||||
import {View, Button, Text} from 'react-native';
|
||||
|
||||
const { Screen, Navigator } = createDrawerNavigator();
|
||||
|
||||
function HomeScreen({ navigation }) {
|
||||
return (
|
||||
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Text>Welcome!</Text>
|
||||
<Button
|
||||
onPress={() => navigation.navigate('Notifications')}
|
||||
title="Go to notifications"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
function NotificationsScreen({ navigation }) {
|
||||
return (
|
||||
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Text>This is the notifications screen</Text>
|
||||
<Button onPress={() => navigation.goBack()} title="Go back home" />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Navigation() {
|
||||
return (
|
||||
<Navigator>
|
||||
<Screen name="Home" component={HomeScreen} />
|
||||
<Screen name="Notifications" component={NotificationsScreen} />
|
||||
</Navigator>
|
||||
);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { render, fireEvent } from '@testing-library/react-native';
|
||||
|
||||
import AppNavigator from '../AppNavigator';
|
||||
|
||||
describe('Testing react navigation', () => {
|
||||
test('page contains the header and 10 items', async () => {
|
||||
const component = (
|
||||
<NavigationContainer>
|
||||
<AppNavigator />
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
const { findByText, findAllByText } = render(component);
|
||||
|
||||
const header = await findByText('List of numbers from 1 to 20');
|
||||
const items = await findAllByText(/Item number/);
|
||||
|
||||
expect(header).toBeTruthy();
|
||||
expect(items.length).toBe(10);
|
||||
});
|
||||
|
||||
test('clicking on one item takes you to the details screen', async () => {
|
||||
const component = (
|
||||
<NavigationContainer>
|
||||
<AppNavigator />
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
const { findByText } = render(component);
|
||||
const toClick = await findByText('Item number 5');
|
||||
|
||||
fireEvent(toClick, 'press');
|
||||
const newHeader = await findByText('Showing details for 5');
|
||||
const newBody = await findByText('the number you have chosen is 5');
|
||||
|
||||
expect(newHeader).toBeTruthy();
|
||||
expect(newBody).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { render, fireEvent } from '@testing-library/react-native';
|
||||
|
||||
import DrawerAppNavigator from '../DrawerAppNavigator';
|
||||
|
||||
describe('Testing react navigation', () => {
|
||||
test('screen contains a button linking to the notifications page', async () => {
|
||||
const component = (
|
||||
<NavigationContainer>
|
||||
<DrawerAppNavigator />
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
const { findByText, findAllByText } = render(component);
|
||||
const button = await findByText('Go to notifications');
|
||||
|
||||
expect(button).toBeTruthy();
|
||||
});
|
||||
|
||||
test('clicking on the button takes you to the notifications screen', async () => {
|
||||
const component = (
|
||||
<NavigationContainer>
|
||||
<DrawerAppNavigator />
|
||||
</NavigationContainer>
|
||||
);
|
||||
|
||||
const { queryByText, findByText } = render(component);
|
||||
const oldScreen = queryByText('Welcome!');
|
||||
const button = await findByText('Go to notifications');
|
||||
|
||||
expect(oldScreen).toBeTruthy();
|
||||
|
||||
fireEvent(button, 'press');
|
||||
const newScreen = await findByText('This is the notifications screen');
|
||||
|
||||
expect(newScreen).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -12,7 +12,7 @@ export default function HomeScreen({ navigation }) {
|
||||
new Array(20).fill(null).map((_, idx) => idx + 1)
|
||||
);
|
||||
|
||||
const onOpacityPress = item => navigation.navigate('Details', item);
|
||||
const onOpacityPress = (item) => navigation.navigate('Details', item);
|
||||
|
||||
return (
|
||||
<View>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import * as React from 'react';
|
||||
import { NavigationContainer } from '@react-navigation/native';
|
||||
import { render } from '@testing-library/react-native';
|
||||
|
||||
/** Render helper that renders `ui` within `NavigationContainer`. */
|
||||
export function renderWithNavigation(ui) {
|
||||
return render(<NavigationContainer>{ui}</NavigationContainer>);
|
||||
}
|
||||
@@ -1,40 +1,27 @@
|
||||
import * as React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { fireEvent, render } from '@testing-library/react-native';
|
||||
import configureStore from '../store';
|
||||
import { screen, fireEvent } from '@testing-library/react-native';
|
||||
import { renderWithRedux } from '../test-utils';
|
||||
import AddTodo from './AddTodo';
|
||||
|
||||
describe('Application test', () => {
|
||||
test('adds a new test when entry has been included', () => {
|
||||
const store = configureStore();
|
||||
test('adds a new todo to redux store when submitting form', () => {
|
||||
const { store } = renderWithRedux(<AddTodo />);
|
||||
|
||||
const component = (
|
||||
<Provider store={store}>
|
||||
<AddTodo />
|
||||
</Provider>
|
||||
);
|
||||
const input = screen.getByPlaceholderText(/repository/i);
|
||||
expect(input).toBeTruthy();
|
||||
|
||||
const { getByPlaceholderText, getByText } = render(component);
|
||||
const textToEnter = 'This is a random element';
|
||||
fireEvent.changeText(input, textToEnter);
|
||||
fireEvent.press(screen.getByText('Submit form'));
|
||||
|
||||
const input = getByPlaceholderText(/repository/i);
|
||||
expect(input).toBeTruthy();
|
||||
|
||||
const textToEnter = 'This is a random element';
|
||||
fireEvent.changeText(input, textToEnter);
|
||||
fireEvent.press(getByText('Submit form'));
|
||||
|
||||
const todosState = store.getState().todos;
|
||||
|
||||
expect(todosState.length).toEqual(1);
|
||||
|
||||
expect(todosState).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: 1,
|
||||
text: textToEnter,
|
||||
date: expect.any(Date),
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
const todosState = store.getState().todos;
|
||||
expect(todosState).toHaveLength(1);
|
||||
expect(todosState).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: 1,
|
||||
text: textToEnter,
|
||||
date: expect.any(Date),
|
||||
}),
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,57 +1,34 @@
|
||||
import * as React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { fireEvent, render } from '@testing-library/react-native';
|
||||
import configureStore from '../store';
|
||||
import { screen, fireEvent } from '@testing-library/react-native';
|
||||
import { renderWithRedux } from '../test-utils';
|
||||
import TodoList from './TodoList';
|
||||
|
||||
describe('Application test', () => {
|
||||
test('it should execute with a store with 4 elements', () => {
|
||||
const initialState = {
|
||||
todos: [
|
||||
{ id: 1, text: 'Sing something', date: new Date() },
|
||||
{ id: 2, text: 'Dance something', date: new Date() },
|
||||
{ id: 3, text: 'Sleep something', date: new Date() },
|
||||
{ id: 4, text: 'Sleep something', date: new Date() },
|
||||
],
|
||||
};
|
||||
const store = configureStore(initialState);
|
||||
const initialState = {
|
||||
todos: [
|
||||
{ id: 1, text: 'Sing something', date: new Date() },
|
||||
{ id: 2, text: 'Dance something', date: new Date() },
|
||||
{ id: 3, text: 'Sleep something', date: new Date() },
|
||||
{ id: 4, text: 'Sleep something', date: new Date() },
|
||||
],
|
||||
};
|
||||
|
||||
const component = (
|
||||
<Provider store={store}>
|
||||
<TodoList />
|
||||
</Provider>
|
||||
);
|
||||
test('it should execute with a store with 4 elements', () => {
|
||||
renderWithRedux(<TodoList />, { initialState });
|
||||
|
||||
const { getAllByText } = render(component);
|
||||
const todoElems = getAllByText(/something/i);
|
||||
|
||||
expect(todoElems.length).toEqual(4);
|
||||
});
|
||||
|
||||
test('should execute with 2 elements and end up with 1 after delete', () => {
|
||||
const initialState = {
|
||||
todos: [
|
||||
{ id: 1, text: 'Sing something', date: new Date() },
|
||||
{ id: 2, text: 'Dance something', date: new Date() },
|
||||
],
|
||||
};
|
||||
const store = configureStore(initialState);
|
||||
|
||||
const component = (
|
||||
<Provider store={store}>
|
||||
<TodoList />
|
||||
</Provider>
|
||||
);
|
||||
|
||||
const { getAllByText } = render(component);
|
||||
const todoElems = getAllByText(/something/i);
|
||||
|
||||
expect(todoElems.length).toBe(2);
|
||||
|
||||
const buttons = getAllByText('Delete');
|
||||
expect(buttons.length).toBe(2);
|
||||
|
||||
fireEvent.press(buttons[0]);
|
||||
expect(getAllByText('Delete').length).toBe(1);
|
||||
});
|
||||
const todoElems = screen.getAllByText(/something/i);
|
||||
expect(todoElems).toHaveLength(4);
|
||||
});
|
||||
|
||||
test('should execute with 2 elements and end up with 1 after delete', () => {
|
||||
renderWithRedux(<TodoList />, { initialState });
|
||||
|
||||
const todoElems = screen.getAllByText(/something/i);
|
||||
expect(todoElems.length).toBe(4);
|
||||
|
||||
const buttons = screen.getAllByText('Delete');
|
||||
expect(buttons).toHaveLength(4);
|
||||
fireEvent.press(buttons[0]);
|
||||
|
||||
const buttonsAfterDelete = screen.getAllByText('Delete');
|
||||
expect(buttonsAfterDelete).toHaveLength(3);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing
|
||||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
|
||||
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
preset: '@testing-library/react-native',
|
||||
setupFiles: ['./jest-setup.js'],
|
||||
};
|
||||
@@ -2,25 +2,22 @@
|
||||
"name": "redux-example",
|
||||
"description": "Testing Redux interactions with RNTL",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "~16.9.0",
|
||||
"react-native": "~0.61.5",
|
||||
"react": "~18.0.0",
|
||||
"react-native": "~0.69.2",
|
||||
"react-redux": "^7.2.0",
|
||||
"redux": "^4.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.8.6",
|
||||
"babel-jest": "~25.2.6",
|
||||
"jest": "~25.2.6",
|
||||
"metro-react-native-babel-preset": "^0.59.0",
|
||||
"@testing-library/react-native": "^7.0.0-rc.0",
|
||||
"react-test-renderer": "~16.9.0"
|
||||
},
|
||||
"private": true,
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
"@babel/core": "^7.9.0",
|
||||
"@testing-library/react-native": "^11.0.0",
|
||||
"@types/jest": "^28.0.0",
|
||||
"jest": "^28.0.0",
|
||||
"metro-react-native-babel-preset": "^0.70.0",
|
||||
"react-test-renderer": "^18.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import * as React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import configureStore from './store';
|
||||
|
||||
export function renderWithRedux(ui, options) {
|
||||
const store = options?.store ?? configureStore(options?.initialState);
|
||||
const queries = render(<Provider store={store}>{ui}</Provider>);
|
||||
return { ...queries, store };
|
||||
}
|
||||
Reference in New Issue
Block a user