Skip to content

Commit

Permalink
Adds integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
chagasaway committed Apr 16, 2019
1 parent 54baafb commit 88a2f73
Show file tree
Hide file tree
Showing 29 changed files with 351 additions and 41 deletions.
2 changes: 1 addition & 1 deletion App.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import App from './src/App';
import { App } from './src/App';

export default App;
5 changes: 5 additions & 0 deletions integration-tests/config/ensureAppFinished.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function ensureAppFinished(duration: number = 1000) {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
}
21 changes: 21 additions & 0 deletions integration-tests/config/matchers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PageObject } from '../page-objects/PageObject';

function toBeVisible<T extends PageObject>(received: T) {
const isVisible = received.isVisible();
return {
message: () => isVisible ? '' : `testID ${received.id} is not visible on the screen`,
pass: isVisible,
};
}

declare global {
namespace jest {
interface Matchers<R> {
toBeVisible(): R;
}
}
}

expect.extend({
toBeVisible,
});
9 changes: 9 additions & 0 deletions integration-tests/config/renderApp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';
import { render } from 'react-native-testing-library';
import { App } from '../../src/App';

export function renderApp() {
return render(
<App />
);
}
15 changes: 15 additions & 0 deletions integration-tests/config/setupQueryMock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import nock from 'nock';
import { QueryMock } from 'graphql-query-test-mock';
import { GRAPHQL_API_URL } from './fetchQuery';

export function setupQueryMock() {
cleanupNock();
const queryMock = new QueryMock();
queryMock.setup(GRAPHQL_API_URL);
return queryMock;
}

function cleanupNock() {
nock.cleanAll();
nock.enableNetConnect();
}
5 changes: 5 additions & 0 deletions integration-tests/mocks/createRequestMoney.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const requestMoney = {
id: 123,
amount: 1000,
qrCode: 'abcde',
};
49 changes: 49 additions & 0 deletions integration-tests/page-objects/AmountInputPageObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { RenderAPI, fireEvent } from 'react-native-testing-library';
import { PageObject } from './PageObject';
import { QRCodePageObject } from './QRCodePageObject';

export class AmountInputPageObject extends PageObject {
private static inputId = 'amountInput';
private static confirmButtonId = 'confirmButton';

constructor(app: RenderAPI) {
super(app, 'AmountInputScreen');
}

public isVisible() {
try {
const input = this.getInput();
return !!input;
} catch {
return false;
}
}

public findByTestIdInPage(testID: string) {
return this.page().find((node) => node.props.testID === testID);
}

public getInput() {
return this.findByTestIdInPage(AmountInputPageObject.inputId);
}

public fillAmount(amount: string) {
const input = this.getInput();
fireEvent.changeText(input, amount);
}

public getAmount() {
const input = this.getInput();
return input.props.value;
}

public getConfirmButton() {
return this.findByTestIdInPage(AmountInputPageObject.confirmButtonId);
}

public confirm = async () => {
const confirmButton = this.getConfirmButton();
await confirmButton.props.onPress({ preventDefault: () => true });
return new QRCodePageObject(this.app);
}
}
21 changes: 21 additions & 0 deletions integration-tests/page-objects/ErrorPageObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RenderAPI, fireEvent } from 'react-native-testing-library';
import { PageObject } from './PageObject';
import { AmountInputPageObject } from './AmountInputPageObject';

export class ErrorPageObject extends PageObject {
private static closeButtonId = 'closeButton';

constructor(app: RenderAPI) {
super(app, 'ErrorScreen');
}

private getCloseButton() {
return this.page().find((node) => node.props.testID === ErrorPageObject.closeButtonId);
}

public async close() {
const closeButton = this.getCloseButton();
fireEvent.press(closeButton);
return new AmountInputPageObject(this.app);
}
}
21 changes: 21 additions & 0 deletions integration-tests/page-objects/PageObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RenderAPI } from 'react-native-testing-library';
import { ReactTestInstance } from 'react-test-renderer';

export abstract class PageObject {
public id: string;
protected app: RenderAPI;

constructor(app: RenderAPI, id: string) {
this.app = app;
this.id = id;
}

public isVisible(): boolean {
const page = this.app.queryByTestId(this.id);
return !!page;
}

protected page(): ReactTestInstance {
return this.app.getByTestId(this.id);
}
}
21 changes: 21 additions & 0 deletions integration-tests/page-objects/QRCodePageObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RenderAPI, fireEvent } from 'react-native-testing-library';
import { PageObject } from './PageObject';
import { AmountInputPageObject } from './AmountInputPageObject';

export class QRCodePageObject extends PageObject {
private static shareButtonId = 'shareButton';

constructor(app: RenderAPI) {
super(app, 'QRCodeScreen');
}

private getCloseButton() {
return this.page().find((node) => node.props.testID === QRCodePageObject.shareButtonId);
}

public async share() {
const shareButton = this.getCloseButton();
fireEvent.press(shareButton);
return new AmountInputPageObject(this.app);
}
}
8 changes: 5 additions & 3 deletions .jestrc.json → jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
module.exports = {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
Expand All @@ -18,5 +18,7 @@
"moduleDirectories": [
"src",
"node_modules"
]
}
],
"automock": false,
"setupFiles": ["./setupJest.ts"]
}
78 changes: 77 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject",
"test": "jest --config .jestrc.json"
"test": "jest --config jest.config.js"
},
"dependencies": {
"expo": "^32.0.0",
Expand All @@ -21,9 +21,12 @@
"@types/react-test-renderer": "16.8.1",
"babel-preset-expo": "^5.0.0",
"jest": "24.7.1",
"jest-fetch-mock": "2.1.2",
"react-native-testing-library": "1.7.0",
"react-test-renderer": "16.8.6",
"ts-jest": "24.0.2",
"typescript": "3.4.3"
"typescript": "3.4.3",
"wait-for-expect": "1.1.1"
},
"private": true
}
}
4 changes: 1 addition & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import { AppNavigator } from './navigation/AppNavigator';
import { createAppContainer } from 'react-navigation';

const App = createAppContainer(AppNavigator);

export default App;
export const App = createAppContainer(AppNavigator);

// const prefix = Expo.Linking.makeUrl('/');

Expand Down
8 changes: 6 additions & 2 deletions src/common/components/BaseScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import React from 'react';
import { StyleSheet, KeyboardAvoidingView } from 'react-native';

export const BaseScreen: React.SFC = ({ children }) => (
<KeyboardAvoidingView style={styles.wrapper} behavior="padding" enabled keyboardVerticalOffset={120}>
interface BaseScreenProps {
testID?: string;
}

export const BaseScreen: React.SFC<BaseScreenProps> = ({ children, testID }) => (
<KeyboardAvoidingView testID={testID} style={styles.wrapper} behavior="padding" enabled keyboardVerticalOffset={120}>
{children}
</KeyboardAvoidingView>
);
Expand Down
5 changes: 3 additions & 2 deletions src/common/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';

export interface ButtonProps {
testID?: string;
onPress: () => void;
label: string;
}

export const Button: React.SFC<ButtonProps> = ({ onPress, label }) => (
<TouchableOpacity style={styles.button} onPress={onPress}>
export const Button: React.SFC<ButtonProps> = ({ testID, onPress, label }) => (
<TouchableOpacity testID={testID} style={styles.button} onPress={onPress}>
<Text style={styles.label}>{label}</Text>
</TouchableOpacity>
);
Expand Down
Loading

0 comments on commit 88a2f73

Please sign in to comment.