mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-23 08:48:12 +00:00
Integration tests (#311)
* Add base test env
* Add eslint rules for cypress
* Add configs and scripts in package json
* Added docker file for bridge and emualator
* Bridge install progress
* Bridge install next step
* Add task for integration tests
* Fixed deps
* Added baseUrl
* Added baseUrl fix
* Added npx
* Added caching for cypress bin
* Added path to binary
* Install cypress
* Finalized dockerfile
* Fixed bridge lib path
* Fixed path for binary
* Adjust script again
* Run all the things properly
* Try to run the tests
* First POC test
* First POC test in gitlab
* Fixed flow
* Fixed gitlab test url, try docker service
* export artifacts
* Test only integration tests in CI
* Test only integration tests in CI 2
* Test only integration tests in CI 3
* Added tests for initialize device
* Try to add docker in only one step
* Turn on other integration steps
* Correct node version
* Ignore cache in flow
* Run bridge and emulator in debug link mode
* Fix param
* Try to run new config in CI
* init device in docker
* Remove docker image after run
* Remove amp
* Fix path
* Artifacts on fail
* Artifacts on fail with volume
* Artifacts on fail with volume 2
* Install mkdir
* Install mkdir again
* test
* test 2
* test 3
* test 4
* test 5
* test 6
* test 7
* test 8
* test 9
* test 10
* test 11
* test 12
* test 13
* test 14
* test 15
* test 16
* test 17
* Revert "test 17"
This reverts commit f3f6c0d690
.
* test 18
* test 19
* test 20
* test 21 try chrome
* test 22
* test 23
* test 24
* test 25
* test 25 try to install chrome again
* test 25 try to install chrome again
* Added missing deps
* Added debug
* Install chromium
* Install chromium 2
* turn on chromium
* turn off debug
* turn on debug
* fix folder
* turn off debug
* Fix init device
* Add header dashboard test
* Bring things back
* clean
* clean fix
* Build image in CI
* Added stage step
* Added docker image
* Added service
* Added tests to docker image
* Refactor a bit
* Correct registry image
* Build wallet again
* Add test for dashbaord content
* new node version, more tests
* Remove unused code
* typo
* Correct snapshots, moved deps to dev, beta disclaimer prop
This commit is contained in:
parent
02a976a759
commit
46fe6d00fc
11
.eslintrc
11
.eslintrc
@ -10,7 +10,8 @@
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"jest": true
|
||||
"jest": true,
|
||||
"cypress/globals": true
|
||||
},
|
||||
"rules": {
|
||||
"import/prefer-default-export": 0,
|
||||
@ -32,13 +33,17 @@
|
||||
"new-cap": 0,
|
||||
"max-len": 0,
|
||||
"eol-last": 0,
|
||||
"spaced-comment": 0
|
||||
"spaced-comment": 0,
|
||||
"no-unused-expressions": 0,
|
||||
"chai-friendly/no-unused-expressions": 2
|
||||
},
|
||||
"plugins": [
|
||||
"import",
|
||||
"react",
|
||||
"jest",
|
||||
"flowtype"
|
||||
"flowtype",
|
||||
"cypress",
|
||||
"chai-friendly"
|
||||
],
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
|
@ -10,6 +10,7 @@
|
||||
.*/_old/.*
|
||||
.*/scripts/solidity/.*
|
||||
.*/build/.*
|
||||
.*/cache/.*
|
||||
|
||||
[libs]
|
||||
./src/flowtype/npm/redux_v3.x.x.js
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -19,4 +19,6 @@ logs
|
||||
|
||||
_old
|
||||
|
||||
coverage
|
||||
coverage
|
||||
test/**/__diff_output__
|
||||
test/screenshots
|
@ -1,14 +1,19 @@
|
||||
image: node:9.3
|
||||
image: node:10.15.1
|
||||
|
||||
variables:
|
||||
CYPRESS_CACHE_FOLDER: "$CI_PROJECT_DIR/cache/Cypress"
|
||||
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- node_modules/
|
||||
- node_modules
|
||||
- ${CYPRESS_CACHE_FOLDER}
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- deploy
|
||||
- integration tests
|
||||
|
||||
lint:
|
||||
stage: test
|
||||
@ -62,7 +67,23 @@ build stable:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build/stable
|
||||
- scripts/s3sync.sh
|
||||
- scripts/s3sync.sh
|
||||
|
||||
build emulator and bridge image:
|
||||
variables:
|
||||
CONTAINER_NAME: "$CI_REGISTRY/emulator-bridge-tests"
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
before_script:
|
||||
- docker login $CI_REGISTRY -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
|
||||
stage: build
|
||||
when: manual
|
||||
script:
|
||||
- docker pull $CONTAINER_NAME:latest || true
|
||||
- docker build --cache-from $CONTAINER_NAME:latest --tag $CONTAINER_NAME:$CI_COMMIT_SHA --tag $CONTAINER_NAME:latest .
|
||||
- docker push $CONTAINER_NAME:$CI_COMMIT_SHA
|
||||
- docker push $CONTAINER_NAME:latest
|
||||
|
||||
deploy review:
|
||||
stage: deploy
|
||||
@ -138,3 +159,24 @@ delete review:
|
||||
- branches
|
||||
tags:
|
||||
- deploy
|
||||
|
||||
integration tests:
|
||||
image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
stage: integration tests
|
||||
script:
|
||||
- 'export SHARED_PATH="$(dirname ${CI_PROJECT_DIR})/shared"'
|
||||
- rm -r ${SHARED_PATH} || true
|
||||
- docker build -t wallet-emulator-bridge-tests .
|
||||
- mkdir -p ${SHARED_PATH}/trezor-wallet/screenshots
|
||||
- mkdir -p ${SHARED_PATH}/trezor-wallet/videos
|
||||
- docker run --volume ${SHARED_PATH}/trezor-wallet/screenshots:/trezor-wallet/test/screenshots --volume ${SHARED_PATH}/trezor-wallet/videos:/trezor-wallet/test/videos --rm wallet-emulator-bridge-tests
|
||||
- find ${SHARED_PATH}
|
||||
- mkdir trezor-wallet
|
||||
- cp -r ${SHARED_PATH}/ trezor-wallet/
|
||||
artifacts:
|
||||
when: always
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- trezor-wallet/
|
53
Dockerfile
53
Dockerfile
@ -1,17 +1,50 @@
|
||||
FROM node:9.3
|
||||
FROM python:latest
|
||||
|
||||
ARG BUILD_TYPE=stable
|
||||
#
|
||||
# setup
|
||||
#
|
||||
RUN apt-get update
|
||||
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
||||
RUN apt-get install -y chromium libappindicator3-1 xdg-utils fonts-liberation nodejs wget dpkg git python python3 python3-pip xvfb libgtk2.0-0 libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2
|
||||
RUN npm install -g yarn
|
||||
|
||||
WORKDIR /trezor-wallet-app
|
||||
RUN ln -s /usr/bin/chromium /usr/local/bin/chromium-browser
|
||||
|
||||
COPY package.json /trezor-wallet-app
|
||||
COPY yarn.lock /trezor-wallet-app
|
||||
#
|
||||
# build emulator
|
||||
#
|
||||
RUN mkdir /trezor-emulator
|
||||
WORKDIR /trezor-emulator
|
||||
|
||||
RUN yarn install
|
||||
RUN git clone https://github.com/trezor/trezor-core
|
||||
WORKDIR /trezor-emulator/trezor-core
|
||||
RUN git submodule update --init --recursive
|
||||
|
||||
COPY . /trezor-wallet-app
|
||||
RUN apt-get install libusb-1.0-0
|
||||
RUN pip3 install scons trezor
|
||||
RUN make build_unix_noui
|
||||
|
||||
RUN yarn run build:${BUILD_TYPE}
|
||||
#
|
||||
# install bridge
|
||||
#
|
||||
RUN mkdir /trezor-bridge
|
||||
WORKDIR /trezor-bridge
|
||||
RUN wget https://wallet.trezor.io/data/bridge/2.0.25/trezor-bridge_2.0.25_amd64.deb
|
||||
RUN dpkg -x /trezor-bridge/trezor-bridge_2.0.25_amd64.deb /trezor-bridge/extracted
|
||||
|
||||
EXPOSE 8080
|
||||
CMD [ "yarn", "run", "prod-server" ]
|
||||
#
|
||||
# install trezor-wallet
|
||||
#
|
||||
RUN mkdir /trezor-wallet
|
||||
WORKDIR /trezor-wallet
|
||||
COPY package.json /trezor-wallet
|
||||
COPY yarn.lock /trezor-wallet
|
||||
RUN yarn
|
||||
COPY . /trezor-wallet
|
||||
RUN yarn run build:stable
|
||||
|
||||
#
|
||||
# run
|
||||
#
|
||||
ENTRYPOINT ["/trezor-wallet/test/scripts/run-all.sh"]
|
||||
EXPOSE 8080 21325
|
11
cypress.json
Normal file
11
cypress.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"integrationFolder": "test/integration",
|
||||
"fixturesFolder": "test/fixtures",
|
||||
"pluginsFile": "test/plugins/index.js",
|
||||
"supportFile": "test/support/index.js",
|
||||
"defaultCommandTimeout": 10000,
|
||||
"screenshotsFolder": "test/screenshots",
|
||||
"video": false,
|
||||
"trashAssetsBeforeRuns": true,
|
||||
"chromeWebSecurity": false
|
||||
}
|
10
package.json
10
package.json
@ -21,10 +21,14 @@
|
||||
"test": "run-s test:*",
|
||||
"test:unit": "npx jest",
|
||||
"test-unit:watch": "npx jest -o --watch",
|
||||
"test-integration:dev": "npx cypress open -c baseUrl=http://localhost:8081/#/",
|
||||
"test-integration:test": "npx cypress run",
|
||||
"test-integration:gitlab": "npx cypress run -c baseUrl=https://localhost:8080/#/ --browser chromium",
|
||||
"server:beta": "node ./server/index.js --buildType=beta",
|
||||
"server:stable": "node ./server/index.js --buildType=stable"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"babel": "^6.23.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"bignumber.js": "2.4.0",
|
||||
@ -69,9 +73,11 @@
|
||||
"redux-logger": "^3.0.6",
|
||||
"redux-raven-middleware": "^1.2.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"request": "^2.88.0",
|
||||
"rimraf": "^2.6.2",
|
||||
"styled-components": "^4.1.2",
|
||||
"styled-normalize": "^8.0.4",
|
||||
"trezor-bridge-communicator": "1.0.2",
|
||||
"trezor-connect": "7.0.0-beta.2",
|
||||
"wallet-address-validator": "^0.2.4",
|
||||
"web3": "1.0.0-beta.35",
|
||||
@ -94,10 +100,14 @@
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"babel-preset-jest": "^23.2.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"cypress": "^3.1.5",
|
||||
"cypress-image-snapshot": "^3.0.0",
|
||||
"eslint": "^4",
|
||||
"eslint-config-airbnb": "^17.0.0",
|
||||
"eslint-import-resolver-babel-module": "^4.0.0",
|
||||
"eslint-loader": "^2.1.0",
|
||||
"eslint-plugin-chai-friendly": "^0.4.1",
|
||||
"eslint-plugin-cypress": "^2.2.0",
|
||||
"eslint-plugin-flowtype": "^2.50.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-jest": "^21.18.0",
|
||||
|
@ -17,6 +17,7 @@ type Props = {
|
||||
isWhite?: boolean,
|
||||
isWebUsb?: boolean,
|
||||
isTransparent?: boolean,
|
||||
dataTest?: string
|
||||
}
|
||||
|
||||
const Wrapper = styled.button`
|
||||
@ -146,10 +147,12 @@ const Button = ({
|
||||
isWhite = false,
|
||||
isWebUsb = false,
|
||||
isTransparent = false,
|
||||
dataTest,
|
||||
}: Props) => {
|
||||
const newClassName = isWebUsb ? `${className} trezor-webusb-button` : className;
|
||||
return (
|
||||
<Wrapper
|
||||
data-test={dataTest}
|
||||
className={newClassName}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
@ -176,6 +179,7 @@ Button.propTypes = {
|
||||
isWhite: PropTypes.bool,
|
||||
isWebUsb: PropTypes.bool,
|
||||
isTransparent: PropTypes.bool,
|
||||
dataTest: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Button;
|
@ -98,11 +98,13 @@ const DeviceHeader = ({
|
||||
disabled = false,
|
||||
isSelected = false,
|
||||
className,
|
||||
testId,
|
||||
}) => {
|
||||
const status = getStatus(device);
|
||||
return (
|
||||
<Wrapper
|
||||
isSelected={isSelected}
|
||||
data-test={testId}
|
||||
isOpen={isOpen}
|
||||
isHoverable={isHoverable}
|
||||
disabled={disabled}
|
||||
@ -134,6 +136,7 @@ DeviceHeader.propTypes = {
|
||||
isSelected: PropTypes.bool,
|
||||
onClickWrapper: PropTypes.func.isRequired,
|
||||
className: PropTypes.string,
|
||||
testId: PropTypes.string,
|
||||
};
|
||||
|
||||
export default DeviceHeader;
|
||||
|
@ -112,7 +112,7 @@ type Props = {
|
||||
};
|
||||
|
||||
const Header = ({ sidebarEnabled, sidebarOpened, toggleSidebar }: Props) => (
|
||||
<Wrapper>
|
||||
<Wrapper data-test="Main__page__navigation">
|
||||
<LayoutWrapper>
|
||||
<Left>
|
||||
{ sidebarEnabled && <MenuToggler onClick={toggleSidebar}>{sidebarOpened ? '✕ Close' : '☰ Menu'}</MenuToggler>}
|
||||
|
@ -68,7 +68,7 @@ const BetaDisclaimer = (props: { close: () => void }) => (
|
||||
/>
|
||||
Please note that the <i>Trezor Beta Wallet</i> might be collecting anonymized usage data, especially error logs, for development purposes. The <i>Trezor Wallet</i> does not log any data.
|
||||
</StyledP>
|
||||
<StyledButton onClick={props.close}>OK, I understand</StyledButton>
|
||||
<StyledButton dataTest="Modal__disclaimer__button__confirm" onClick={props.close}>OK, I understand</StyledButton>
|
||||
</ModalWindow>
|
||||
</Wrapper>
|
||||
);
|
||||
|
@ -57,7 +57,7 @@ class CoinMenu extends PureComponent<Props> {
|
||||
render() {
|
||||
const { config } = this.props.localStorage;
|
||||
return (
|
||||
<Wrapper>
|
||||
<Wrapper data-test="Main__page__coin__menu">
|
||||
{config.networks.map(item => (
|
||||
<NavLink
|
||||
key={item.shortcut}
|
||||
@ -72,6 +72,7 @@ class CoinMenu extends PureComponent<Props> {
|
||||
</NavLink>
|
||||
))}
|
||||
<Divider
|
||||
testId="Main__page__coin__menu__divider"
|
||||
textLeft="Other coins"
|
||||
textRight="(You will be redirected)"
|
||||
hasBorder
|
||||
|
@ -23,9 +23,10 @@ const TextLeft = styled.p`
|
||||
`;
|
||||
|
||||
const Divider = ({
|
||||
textLeft, textRight, hasBorder = false, className,
|
||||
textLeft, textRight, hasBorder = false, className, testId,
|
||||
}) => (
|
||||
<Wrapper
|
||||
data-test={testId}
|
||||
hasBorder={hasBorder}
|
||||
className={className}
|
||||
>
|
||||
@ -39,6 +40,7 @@ Divider.propTypes = {
|
||||
textLeft: PropTypes.string,
|
||||
textRight: PropTypes.string,
|
||||
hasBorder: PropTypes.bool,
|
||||
testId: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Divider;
|
||||
|
@ -207,6 +207,7 @@ class LeftNavigation extends React.PureComponent<Props, State> {
|
||||
<Sidebar isOpen={props.wallet.showSidebar}>
|
||||
<Header
|
||||
isSelected
|
||||
testId="Main__page__device__header"
|
||||
isHoverable={false}
|
||||
onClickWrapper={() => {
|
||||
if (isDeviceAccessible || this.props.devices.length > 1) {
|
||||
@ -237,7 +238,7 @@ class LeftNavigation extends React.PureComponent<Props, State> {
|
||||
{dropdownOpened && <DeviceMenu ref={this.deviceMenuRef} {...this.props} />}
|
||||
{isDeviceAccessible && menu}
|
||||
</Body>
|
||||
<Footer key="sticky-footer">
|
||||
<Footer data-test="Main__page__footer" key="sticky-footer">
|
||||
<Help>
|
||||
<A
|
||||
href="https://trezor.io/support/"
|
||||
|
@ -114,7 +114,11 @@ const StyledBackdrop = styled(Backdrop)`
|
||||
|
||||
const Wallet = (props: Props) => (
|
||||
<AppWrapper>
|
||||
<Header sidebarEnabled={!!props.wallet.selectedDevice} sidebarOpened={props.wallet.showSidebar} toggleSidebar={props.toggleSidebar} />
|
||||
<Header
|
||||
sidebarEnabled={!!props.wallet.selectedDevice}
|
||||
sidebarOpened={props.wallet.showSidebar}
|
||||
toggleSidebar={props.toggleSidebar}
|
||||
/>
|
||||
<AppNotifications />
|
||||
<WalletWrapper>
|
||||
<StyledBackdrop show={props.wallet.showSidebar} onClick={props.toggleSidebar} animated />
|
||||
|
@ -49,7 +49,7 @@ const Image = styled.img`
|
||||
const Dashboard = () => (
|
||||
<Content>
|
||||
<Wrapper>
|
||||
<Row>
|
||||
<Row data-test="Dashboard__page__content">
|
||||
<H1>Please select your coin</H1>
|
||||
<StyledP>You will gain access to receiving & sending selected coin</StyledP>
|
||||
<Overlay>
|
||||
|
@ -26,7 +26,7 @@ const StyledParagraph = styled(Paragraph)`
|
||||
`;
|
||||
|
||||
const Initialize = () => (
|
||||
<Wrapper>
|
||||
<Wrapper data-test="Page__device__not__initialized">
|
||||
<Row>
|
||||
<H1>Your device is not initialized</H1>
|
||||
<StyledParagraph>Please use Bitcoin wallet interface to start initialization process</StyledParagraph>
|
||||
|
26
test/integration/dashboard.spec.js
Normal file
26
test/integration/dashboard.spec.js
Normal file
@ -0,0 +1,26 @@
|
||||
describe('Dashboard page', () => {
|
||||
beforeEach(() => {
|
||||
cy.viewport(1366, 1800);
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
it('navigation', () => {
|
||||
cy.getTestElement('Main__page__navigation')
|
||||
.should('be.visible')
|
||||
.matchImageSnapshot();
|
||||
});
|
||||
|
||||
it('content', () => {
|
||||
cy.getTestElement('Dashboard__page__content')
|
||||
.should('be.visible')
|
||||
.matchImageSnapshot();
|
||||
});
|
||||
|
||||
// Menu
|
||||
|
||||
it('device header', () => {
|
||||
cy.getTestElement('Main__page__device__header')
|
||||
.should('be.visible')
|
||||
.matchImageSnapshot();
|
||||
});
|
||||
});
|
7
test/plugins/index.js
Normal file
7
test/plugins/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
const {
|
||||
addMatchImageSnapshotPlugin,
|
||||
} = require('cypress-image-snapshot/plugin');
|
||||
|
||||
module.exports = (on) => {
|
||||
addMatchImageSnapshotPlugin(on);
|
||||
};
|
6
test/scripts/init-device.js
Normal file
6
test/scripts/init-device.js
Normal file
@ -0,0 +1,6 @@
|
||||
import '@babel/polyfill';
|
||||
import { initSeedAllDevice } from 'trezor-bridge-communicator';
|
||||
|
||||
(async () => {
|
||||
await initSeedAllDevice();
|
||||
})();
|
20
test/scripts/run-all.sh
Executable file
20
test/scripts/run-all.sh
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# go to root
|
||||
cd "$(dirname "$0")"
|
||||
cd ..
|
||||
|
||||
# run bridge
|
||||
cd /trezor-bridge && ./extracted/usr/bin/trezord -ed 21324:21325 -u=false &
|
||||
|
||||
# run emulator
|
||||
cd /trezor-emulator/trezor-core && PYOPT=0 ./emu.sh &
|
||||
|
||||
# run wallet
|
||||
cd /trezor-wallet && yarn run server:stable &
|
||||
|
||||
# init device
|
||||
npx babel-node /trezor-wallet/test/scripts/init-device.js &
|
||||
|
||||
# run tests
|
||||
yarn run test-integration:gitlab -c baseUrl="https://localhost:8080/#/"
|
BIN
test/snapshots/All Specs/Dashboard page -- content.snap.png
Normal file
BIN
test/snapshots/All Specs/Dashboard page -- content.snap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
test/snapshots/All Specs/Dashboard page -- navigation.snap.png
Normal file
BIN
test/snapshots/All Specs/Dashboard page -- navigation.snap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
5
test/support/commands.js
Normal file
5
test/support/commands.js
Normal file
@ -0,0 +1,5 @@
|
||||
import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command';
|
||||
|
||||
addMatchImageSnapshotCommand();
|
||||
|
||||
Cypress.Commands.add('getTestElement', selector => cy.get(`[data-test="${selector}"]`));
|
5
test/support/index.js
Normal file
5
test/support/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
import './commands';
|
||||
|
||||
beforeEach(() => {
|
||||
window.localStorage.setItem('/betaModalPrivacy', true);
|
||||
});
|
Loading…
Reference in New Issue
Block a user