diff --git a/__tests__/components/button.test.js b/__tests__/components/button.test.js
new file mode 100644
index 0000000..638d909
--- /dev/null
+++ b/__tests__/components/button.test.js
@@ -0,0 +1,42 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { Button } from '../../app/components/button';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render primary button correctly', () => {
+ const { queryByTestId } = render(
+
+
+ );
+
+ expect(queryByTestId('PrimaryButton')).toBeInTheDocument();
+ });
+
+ test('should render secondary button correctly', () => {
+ const { queryByTestId } = render(
+
+
+ );
+
+ expect(queryByTestId('SecondaryButton')).toBeInTheDocument();
+ });
+
+});
diff --git a/__tests__/components/clipboard.test.js b/__tests__/components/clipboard.test.js
new file mode 100644
index 0000000..5645f60
--- /dev/null
+++ b/__tests__/components/clipboard.test.js
@@ -0,0 +1,34 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { Clipboard } from '../../app/components/clipboard';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render clipboard component correctly', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+
+ expect(queryByTestId('Clipboard')).toBeInTheDocument();
+ });
+
+ test('should render clipboard button correctly', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+
+ expect(queryByTestId('PrimaryButton')).toBeInTheDocument();
+ });
+
+});
diff --git a/__tests__/components/column.test.js b/__tests__/components/column.test.js
new file mode 100644
index 0000000..5cdb0ef
--- /dev/null
+++ b/__tests__/components/column.test.js
@@ -0,0 +1,28 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { ColumnComponent } from '../../app/components/column';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render correctly', () => {
+ // $FlowFixMe
+ const { container } = render(
+
+
+ ZEC
+ React
+ Wallet
+
+ ,
+ );
+
+ expect(container).toBeVisible();
+ });
+});
diff --git a/__tests__/components/confirm-dialog.test.js b/__tests__/components/confirm-dialog.test.js
new file mode 100644
index 0000000..04f189f
--- /dev/null
+++ b/__tests__/components/confirm-dialog.test.js
@@ -0,0 +1,39 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import 'jest-dom/extend-expect';
+
+import { ConfirmDialogComponent } from '../../app/components/confirm-dialog';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render confirm dialog correctly', () => {
+ const { container } = render(
+ alert('Confirm')}
+ renderTrigger={toggle => }
+ >
+ {toggle => Confirm content
}
+ ,
+ );
+
+ expect(container).toBeVisible();
+ });
+
+ test('should render confirm dialog trigger', () => {
+ const { queryByTestId } = render(
+ alert('Confirm')}
+ renderTrigger={toggle => }
+ >
+ {toggle => Confirm content
}
+ ,
+ );
+
+ expect(queryByTestId('ConfirmDialogTrigger')).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/divider.test.js b/__tests__/components/divider.test.js
new file mode 100644
index 0000000..fe2c1c4
--- /dev/null
+++ b/__tests__/components/divider.test.js
@@ -0,0 +1,27 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { Divider } from '../../app/components/divider';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render correctly', () => {
+ // $FlowFixMe
+ const { container } = render(
+
+
+ ,
+ );
+
+ const divider = container.querySelector('div');
+
+ expect(divider).toBeVisible();
+ expect(divider).toHaveStyle('opacity: 0.3');
+ });
+});
diff --git a/__tests__/components/dropdown.test.js b/__tests__/components/dropdown.test.js
new file mode 100644
index 0000000..8bdea6a
--- /dev/null
+++ b/__tests__/components/dropdown.test.js
@@ -0,0 +1,64 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { DropdownComponent } from '../../app/components/dropdown';
+import { Button } from '../../app/components/button';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render dropdown correctly', () => {
+ const { queryByTestId } = render(
+
+
+ (
+
+ )}
+ options={[
+ { label: 'asbh1yeasbdh23848asdasd', onClick: console.log },
+ { label: 'urtyruhjr374hbfdjdhuh', onClick: console.log },
+ ]}
+ />
+
+ ,
+ );
+
+ expect(queryByTestId('DropdownWrapper')).toBeInTheDocument();
+ });
+
+ test('should render dropdown button trigger correctly', () => {
+ const { queryByTestId } = render(
+
+
+ (
+
+ )}
+ options={[
+ { label: 'asbh1yeasbdh23848asdasd', onClick: console.log },
+ { label: 'urtyruhjr374hbfdjdhuh', onClick: console.log },
+ ]}
+ />
+
+ ,
+ );
+
+ expect(queryByTestId('PrimaryButton')).toBeInTheDocument();
+ });
+
+});
diff --git a/__tests__/components/empty-transactions.test.js b/__tests__/components/empty-transactions.test.js
new file mode 100644
index 0000000..95e3fd4
--- /dev/null
+++ b/__tests__/components/empty-transactions.test.js
@@ -0,0 +1,33 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup, queryByText } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { EmptyTransactionsComponent } from '../../app/components/empty-transactions';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render correctly', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+
+ expect(queryByTestId('NoTransactions')).toBeInTheDocument();
+ });
+
+ test('should show label correctly', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /transactions/i)).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/input-label.test.js b/__tests__/components/input-label.test.js
new file mode 100644
index 0000000..881b890
--- /dev/null
+++ b/__tests__/components/input-label.test.js
@@ -0,0 +1,35 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup, queryByText } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { InputLabelComponent } from '../../app/components/input-label';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render correctly', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ const label = container.querySelector('p');
+
+ expect(label).toBeVisible();
+ });
+
+ test('should render input label string', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /From/i)).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/input.test.js b/__tests__/components/input.test.js
new file mode 100644
index 0000000..01970a7
--- /dev/null
+++ b/__tests__/components/input.test.js
@@ -0,0 +1,42 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { InputComponent } from '../../app/components/input';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render text input correctly', () => {
+ const { queryByTestId } = render(
+
+
+
+ );
+
+ expect(queryByTestId('Input')).toBeInTheDocument();
+ });
+
+ test('should render textarea correctly', () => {
+ const { queryByTestId } = render(
+
+
+
+ );
+
+ expect(queryByTestId('Textarea')).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/loading-screen.test.js b/__tests__/components/loading-screen.test.js
new file mode 100644
index 0000000..15debb1
--- /dev/null
+++ b/__tests__/components/loading-screen.test.js
@@ -0,0 +1,23 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { LoadingScreen } from '../../app/components/loading-screen';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render status pill correctly', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+
+ expect(queryByTestId('LoadingScreen')).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/modal.test.js b/__tests__/components/modal.test.js
new file mode 100644
index 0000000..f77b053
--- /dev/null
+++ b/__tests__/components/modal.test.js
@@ -0,0 +1,35 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import 'jest-dom/extend-expect';
+
+import { ModalComponent } from '../../app/components/modal';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render modal trigger correctly', () => {
+ const { queryByTestId } = render(
+ (
+
+ )}
+ >
+ {toggleVisibility => (
+
+ Modal Content
+
+
+ )}
+ ,
+ );
+
+ expect(queryByTestId('ModalTrigger')).toBeInTheDocument();
+ });
+
+});
diff --git a/__tests__/components/qrcode.test.js b/__tests__/components/qrcode.test.js
new file mode 100644
index 0000000..7960b31
--- /dev/null
+++ b/__tests__/components/qrcode.test.js
@@ -0,0 +1,19 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import 'jest-dom/extend-expect';
+
+import { QRCode } from '../../app/components/qrcode';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render qrcode component correctly', () => {
+ const { queryByTestId } = render(
+ ,
+ );
+
+ expect(queryByTestId('QRCode')).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/row.test.js b/__tests__/components/row.test.js
new file mode 100644
index 0000000..1b08c33
--- /dev/null
+++ b/__tests__/components/row.test.js
@@ -0,0 +1,27 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { RowComponent } from '../../app/components/row';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render correctly', () => {
+ const { container } = render(
+
+
+ ZEC
+ React
+ Wallet
+
+ ,
+ );
+
+ expect(container).toBeVisible();
+ });
+});
diff --git a/__tests__/components/select.test.js b/__tests__/components/select.test.js
new file mode 100644
index 0000000..844ff25
--- /dev/null
+++ b/__tests__/components/select.test.js
@@ -0,0 +1,67 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup, queryByText } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { SelectComponent } from '../../app/components/select';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should generate snapshot correctly', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container).toBeVisible();
+ });
+
+ test('should render correctly', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+
+ expect(queryByTestId('Select')).toBeInTheDocument();
+ });
+
+ test('should render select trigger string', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /Select/i)).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/status-pill.test.js b/__tests__/components/status-pill.test.js
new file mode 100644
index 0000000..4de74b5
--- /dev/null
+++ b/__tests__/components/status-pill.test.js
@@ -0,0 +1,54 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup, queryByText } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { StatusPill } from '../../app/components/status-pill';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render status pill correctly', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+
+ expect(queryByTestId('StatusPill')).toBeInTheDocument();
+ });
+
+ test('should show percentage on status pill syncing', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /%/i)).toBeInTheDocument();
+ });
+
+ test('should hide percentage on status pill', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /%/i)).not.toBeInTheDocument();
+ });
+
+ test('should show error string and hide percentage on status pill', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /%/i)).not.toBeInTheDocument();
+ expect(queryByText(container, /error/i)).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/text.test.js b/__tests__/components/text.test.js
new file mode 100644
index 0000000..5580a34
--- /dev/null
+++ b/__tests__/components/text.test.js
@@ -0,0 +1,33 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup, queryByText } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { TextComponent } from '../../app/components/text';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render correctly', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container).toBeVisible();
+ });
+
+ test('should render input label string', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(queryByText(container, /Test/i)).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/components/transaction-item.test.js b/__tests__/components/transaction-item.test.js
new file mode 100644
index 0000000..e75fd4a
--- /dev/null
+++ b/__tests__/components/transaction-item.test.js
@@ -0,0 +1,31 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { TransactionItemComponent } from '../../app/components/transaction-item';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render a transaction item correctly', () => {
+ const { container } = render(
+
+
+
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+
+});
diff --git a/__tests__/components/transactions-daily.test.js b/__tests__/components/transactions-daily.test.js
new file mode 100644
index 0000000..a999ded
--- /dev/null
+++ b/__tests__/components/transactions-daily.test.js
@@ -0,0 +1,46 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { TransactionDailyComponent } from '../../app/components/transaction-daily';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ describe('render()', () => {
+ test('should render user daily transactions', () => {
+ const { container } = render(
+
+
+ ,
+ );
+
+ expect(container).toMatchSnapshot();
+ });
+ });
+});
diff --git a/__tests__/components/wallet-address.test.js b/__tests__/components/wallet-address.test.js
new file mode 100644
index 0000000..f3cc150
--- /dev/null
+++ b/__tests__/components/wallet-address.test.js
@@ -0,0 +1,27 @@
+// @flow
+
+import React from 'react';
+import { render, cleanup, queryByText } from 'react-testing-library';
+import { ThemeProvider } from 'styled-components';
+import 'jest-dom/extend-expect';
+
+import { WalletAddress } from '../../app/components/wallet-address';
+import appTheme from '../../app/theme';
+
+afterEach(cleanup);
+
+describe('', () => {
+ test('should render wallet address component correctly', () => {
+ const { queryByTestId } = render(
+
+
+
+
+ ,
+ );
+
+ expect(queryByTestId('Address')).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/setup/assetTransformer.js b/__tests__/setup/assetTransformer.js
new file mode 100644
index 0000000..1f173b0
--- /dev/null
+++ b/__tests__/setup/assetTransformer.js
@@ -0,0 +1,7 @@
+const path = require('path');
+
+module.exports = {
+ process(filename) {
+ return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
+ },
+};
\ No newline at end of file
diff --git a/app/components/button.js b/app/components/button.js
index f3291cf..5a44bf7 100644
--- a/app/components/button.js
+++ b/app/components/button.js
@@ -102,12 +102,12 @@ export const Button = ({
const buttonLabel = isLoading ? 'Loading...' : label;
const component = variant === 'primary' ? (
-
+
{icon ? : null}
{buttonLabel}
) : (
-
+
{icon ? : null}
{buttonLabel}
diff --git a/app/components/clipboard.js b/app/components/clipboard.js
index bda14ca..7f42e61 100644
--- a/app/components/clipboard.js
+++ b/app/components/clipboard.js
@@ -39,12 +39,14 @@ export class Clipboard extends PureComponent {
const { copied } = this.state;
return (
-
+
+
+
);
}
}
diff --git a/app/components/dropdown.js b/app/components/dropdown.js
index 3bd880c..2eca400 100644
--- a/app/components/dropdown.js
+++ b/app/components/dropdown.js
@@ -107,7 +107,7 @@ export class DropdownComponent extends Component {
)}
{options.map(({ label: optionLabel, onClick }) => (
-
+
))}
diff --git a/app/components/empty-transactions.js b/app/components/empty-transactions.js
index c0247f0..6d5ce99 100644
--- a/app/components/empty-transactions.js
+++ b/app/components/empty-transactions.js
@@ -13,7 +13,7 @@ const Wrapper = styled.div`
`;
export const EmptyTransactionsComponent = () => (
-
+
);
diff --git a/app/components/header.js b/app/components/header.js
index acbbf9b..ade949e 100644
--- a/app/components/header.js
+++ b/app/components/header.js
@@ -9,6 +9,8 @@ import { Divider } from './divider';
import { RowComponent } from './row';
import { StatusPill } from './status-pill';
+import { withSyncStatus } from '../../services/sync-status';
+
const Wrapper = styled.div`
height: ${props => props.theme.headerHeight};
width: 100vw;
@@ -59,6 +61,8 @@ type Props = {
title: string,
};
+const Status = withSyncStatus(StatusPill);
+
export const HeaderComponent = ({ title }: Props) => (