From be469d4cec74ee71324c1bc41398b982b4176566 Mon Sep 17 00:00:00 2001 From: Fabian Date: Fri, 9 Feb 2018 21:36:20 +0000 Subject: [PATCH 01/37] added e2e tests to circleci --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index d91cbf1338..de883b2c60 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,4 +30,5 @@ jobs: key: v1-dependencies-root-{{ checksum "package.json" }} - run: yarn run test + - run: yarn run test:e2e - run: bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN From 13d5e89d6090733618bdfa50ad80b6d4bcb7839c Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 13:31:44 +0100 Subject: [PATCH 02/37] trying to add gaia package --- .circleci/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index de883b2c60..c51f985e77 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,6 +8,8 @@ jobs: docker: # specify the version you desire here - image: circleci/node:9.4.0-browsers + environment: + - BINARY_PATH: "usr/bin/gaia" working_directory: ~/repo @@ -28,6 +30,10 @@ jobs: - yarn.lock - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} + + - run: wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | apt-key add + - run: wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list + - run: apt-get update && apt-get install gaia - run: yarn run test - run: yarn run test:e2e From 9b788ec3cc92bc58b511a4c33f198f5b0ebb58e2 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 13:34:38 +0100 Subject: [PATCH 03/37] use sudo for gaia installation --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c51f985e77..165871b861 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,9 +31,9 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - - run: wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | apt-key add - - run: wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - - run: apt-get update && apt-get install gaia + - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | apt-key add + - run: sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list + - run: sudo apt-get update && sudo apt-get install gaia - run: yarn run test - run: yarn run test:e2e From 8bff9290d26b056577f14174fed1c05fc12dd51b Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 13:36:04 +0100 Subject: [PATCH 04/37] added missing sudo --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 165871b861..998467ab05 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | apt-key add + - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - run: sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - run: sudo apt-get update && sudo apt-get install gaia From 0850ee65ab7d77f324c42786a5fa5d27b0003dcc Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 13:39:47 +0100 Subject: [PATCH 05/37] remove pgp key getter --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 998467ab05..f12ad48b58 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add + # - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - run: sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - run: sudo apt-get update && sudo apt-get install gaia From 028eeb36901fa28ba2303e98bfbf562571a1d418 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 13:39:47 +0100 Subject: [PATCH 06/37] Revert "remove pgp key getter" This reverts commit 0850ee65ab7d77f324c42786a5fa5d27b0003dcc. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f12ad48b58..998467ab05 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - # - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add + - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - run: sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - run: sudo apt-get update && sudo apt-get install gaia From 40fb38faeaa506a36d0ad9246a3d2a140c4e98be Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 13:42:48 +0100 Subject: [PATCH 07/37] fixed wrong pgp getter command --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 998467ab05..410a41a554 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,7 +31,7 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - - run: sudo wget https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add + - run: sudo wget -O - https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - - run: sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - run: sudo apt-get update && sudo apt-get install gaia From 289eb4377fc5b6f71fde9cf5ed6c21524568d162 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 14:09:39 +0100 Subject: [PATCH 08/37] removing gaia post install --- .circleci/config.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 410a41a554..7047756be9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,9 +31,15 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - - run: sudo wget -O - https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - - - run: sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - - run: sudo apt-get update && sudo apt-get install gaia + - run: + command: | + sudo wget -O - https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - + sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list + apt-get download gaia + sudo dpkg --unpack gaia*.deb + sudo rm /var/lib/dpkg/info/gaia.postinst -f + sudo dpkg --configure gaia + sudo apt-get install -yf - run: yarn run test - run: yarn run test:e2e From 8efe049ec875175c10c4e219be81aaecbda03a48 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 14:15:15 +0100 Subject: [PATCH 09/37] fixing apt-get download by doing an update before --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7047756be9..db8e0490d8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,10 +31,13 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} + # add gaia - run: command: | sudo wget -O - https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list + sudo apt-key update + sudo apt-get update apt-get download gaia sudo dpkg --unpack gaia*.deb sudo rm /var/lib/dpkg/info/gaia.postinst -f From e7d5ad30fa3c897f9127062742d37732f10ecbd7 Mon Sep 17 00:00:00 2001 From: Fabian Date: Mon, 12 Feb 2018 14:36:43 +0100 Subject: [PATCH 10/37] trying to fix missing dependencies --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index db8e0490d8..7ea7a71385 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -39,6 +39,7 @@ jobs: sudo apt-key update sudo apt-get update apt-get download gaia + sudo apt-get -f install sudo dpkg --unpack gaia*.deb sudo rm /var/lib/dpkg/info/gaia.postinst -f sudo dpkg --configure gaia From 6716341a25de09262a68f179ec32a71019722bc4 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 13:38:19 +0000 Subject: [PATCH 11/37] try selfhosted gaia --- .circleci/config.yml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ea7a71385..ca877a0f7b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,7 @@ jobs: # specify the version you desire here - image: circleci/node:9.4.0-browsers environment: - - BINARY_PATH: "usr/bin/gaia" + - BINARY_PATH: "~/repo/gaia" working_directory: ~/repo @@ -34,16 +34,7 @@ jobs: # add gaia - run: command: | - sudo wget -O - https://tendermint-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-Tendermint | sudo apt-key add - - sudo wget -O /etc/apt/sources.list.d/tendermint.list https://tendermint-packages.interblock.io/debian/tendermint.list - sudo apt-key update - sudo apt-get update - apt-get download gaia - sudo apt-get -f install - sudo dpkg --unpack gaia*.deb - sudo rm /var/lib/dpkg/info/gaia.postinst -f - sudo dpkg --configure gaia - sudo apt-get install -yf + sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia - run: yarn run test - run: yarn run test:e2e From 12bee4177fe5539c215821f468a0750b503f3aad Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 13:41:08 +0000 Subject: [PATCH 12/37] try other path --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ca877a0f7b..28057ecb26 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,7 +9,7 @@ jobs: # specify the version you desire here - image: circleci/node:9.4.0-browsers environment: - - BINARY_PATH: "~/repo/gaia" + - BINARY_PATH: "/home/circleci/repo/gaia" working_directory: ~/repo From 918815283ce20b35a936ae5d3fca2f054e50e082 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 13:49:27 +0000 Subject: [PATCH 13/37] try to set rights to execute gaia --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 28057ecb26..2d989ab5db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,6 +35,7 @@ jobs: - run: command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia + chmod o+wx /home/circleci/repo/gaia - run: yarn run test - run: yarn run test:e2e From a7ec488c1aa2a54c6ebeb9dd23a12517c682ec91 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 13:50:36 +0000 Subject: [PATCH 14/37] using sudo to change rights --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2d989ab5db..3a423b6bc5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,7 +35,7 @@ jobs: - run: command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia - chmod o+wx /home/circleci/repo/gaia + sudo chmod o+wx /home/circleci/repo/gaia - run: yarn run test - run: yarn run test:e2e From f64d52ce39123520646b8717283896031c44b733 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 14:07:22 +0000 Subject: [PATCH 15/37] setting headless mode --- test/e2e/launch.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/launch.js b/test/e2e/launch.js index 95cf2f8b8b..b723998537 100644 --- a/test/e2e/launch.js +++ b/test/e2e/launch.js @@ -34,6 +34,7 @@ module.exports = function launch (t) { path: electron, args: [ join(__dirname, '../../app/dist/main.js'), + '--headless', '--disable-gpu', '--no-sandbox' ], @@ -116,7 +117,7 @@ async function startLocalNode () { 'node', 'init', 'D0718DDFF62D301626B428A182F830CBB0AD21FC', '--home', cliHome, - '--chain-id' , 'localtestnet' + '--chain-id' , 'localtestnet' ]) child.once('exit', (code) => { if (code === 0) resolve() From 65be7a778ccacd9d86e72bf95a3e6da7b78cf415 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 14:17:56 +0000 Subject: [PATCH 16/37] trying to fix issue with wallet test --- test/e2e/wallet.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/e2e/wallet.js b/test/e2e/wallet.js index 995bbc3afb..03838d403a 100644 --- a/test/e2e/wallet.js +++ b/test/e2e/wallet.js @@ -21,6 +21,8 @@ function cliSendCoins (home, to, amount) { } test('wallet', async function (t) { + await sleep(500) + let {app, home} = await launchApp(t) let client = app.client let $ = (...args) => client.$(...args) From dbac2f5c1d89b50a65348e6f7ddedb8951d73d5f Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 14:26:24 +0000 Subject: [PATCH 17/37] trying more stuff --- package.json | 2 +- test/e2e/common.js | 3 +++ test/e2e/wallet.js | 2 -- yarn.lock | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8b2fa40d98..e8a93a5372 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "node-sass": "^4.7.2", "proxyquire": "^1.8.0", "pug": "^2.0.0-rc.1", - "spectron": "^3.7.2", + "spectron": "^3.8.0", "style-loader": "^0.19.1", "tape": "^4.8.0", "tape-promise": "^2.0.1", diff --git a/test/e2e/common.js b/test/e2e/common.js index 6a4a18ca91..64d07dabac 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -57,6 +57,9 @@ module.exports = { }, async logout (client) { console.log('logging out') + if (await client.isExisting('.ni-li-session')) { + return + } await module.exports.openMenu(client) await client.$('.ni-li-user').click() diff --git a/test/e2e/wallet.js b/test/e2e/wallet.js index 03838d403a..995bbc3afb 100644 --- a/test/e2e/wallet.js +++ b/test/e2e/wallet.js @@ -21,8 +21,6 @@ function cliSendCoins (home, to, amount) { } test('wallet', async function (t) { - await sleep(500) - let {app, home} = await launchApp(t) let client = app.client let $ = (...args) => client.$(...args) diff --git a/yarn.lock b/yarn.lock index 7fa33eaffb..129d9163f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7529,7 +7529,7 @@ spdy@^3.4.1: select-hose "^2.0.0" spdy-transport "^2.0.18" -spectron@^3.7.2: +spectron@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/spectron/-/spectron-3.8.0.tgz#122c3562fd7e92b7cdf6f94094aa495b150dfa51" dependencies: From 635b8888382418b8d34a9abbdceb404dc69268de Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 14:31:45 +0000 Subject: [PATCH 18/37] wait more so click is possible --- test/e2e/wallet.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/e2e/wallet.js b/test/e2e/wallet.js index 995bbc3afb..0f94f910c4 100644 --- a/test/e2e/wallet.js +++ b/test/e2e/wallet.js @@ -24,7 +24,8 @@ test('wallet', async function (t) { let {app, home} = await launchApp(t) let client = app.client let $ = (...args) => client.$(...args) - + + await sleep(500) await logout(client) await login(client, 'testkey') From 759aac9c09cba49dd517c88cee9c1b11994c4a67 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 14:35:09 +0000 Subject: [PATCH 19/37] waiting more --- test/e2e/common.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/common.js b/test/e2e/common.js index 64d07dabac..06decc2f8d 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -63,6 +63,7 @@ module.exports = { await module.exports.openMenu(client) await client.$('.ni-li-user').click() + await sleep(300) await client.$('.material-icons=exit_to_app').$('..').click() } } From ba963ac4dd461e4681316752356840d943989ce4 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:01:28 +0000 Subject: [PATCH 20/37] add more logging --- test/e2e/common.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/e2e/common.js b/test/e2e/common.js index 06decc2f8d..03d813b675 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -13,7 +13,7 @@ module.exports = { // close notifications as they overlay the menu button while (await client.isExisting(`.ni-notification`)) { await client.$(`.ni-notification`).click() - } + } await client.waitForExist('.material-icons=menu', 1000) await client.$('.material-icons=menu').click() await client.waitForExist('.app-menu', 1000) @@ -60,10 +60,12 @@ module.exports = { if (await client.isExisting('.ni-li-session')) { return } + console.log('open menu') await module.exports.openMenu(client) await client.$('.ni-li-user').click() await sleep(300) + console.log('clicking logout') await client.$('.material-icons=exit_to_app').$('..').click() } } From 7cbc44e4bd385415302eefe7fcfcff8a3041454a Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:13:43 +0000 Subject: [PATCH 21/37] update chrome --- .circleci/config.yml | 12 +++++++++++- test/e2e/common.js | 4 +--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3a423b6bc5..c5d4d8247b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,8 +31,18 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - # add gaia + - run: + name: Install Chromedriver latest version + command: | + sudo apt-get update + sudo apt-get install lsb-release + curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb12 + sudo dpkg -i google-chrome.deb + sudo sed -i ‘s|HERE/chrome"|HERE/chrome" --disable-setuid-sandbox|g’ /opt/google/chrome/google-chrome + rm google-chrome.deb + - run: + name: Add Gaia command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia sudo chmod o+wx /home/circleci/repo/gaia diff --git a/test/e2e/common.js b/test/e2e/common.js index 03d813b675..06decc2f8d 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -13,7 +13,7 @@ module.exports = { // close notifications as they overlay the menu button while (await client.isExisting(`.ni-notification`)) { await client.$(`.ni-notification`).click() - } + } await client.waitForExist('.material-icons=menu', 1000) await client.$('.material-icons=menu').click() await client.waitForExist('.app-menu', 1000) @@ -60,12 +60,10 @@ module.exports = { if (await client.isExisting('.ni-li-session')) { return } - console.log('open menu') await module.exports.openMenu(client) await client.$('.ni-li-user').click() await sleep(300) - console.log('clicking logout') await client.$('.material-icons=exit_to_app').$('..').click() } } From d5067ce34413e1751c8f4f1f8c92a34edcbad344 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:18:37 +0000 Subject: [PATCH 22/37] set chrome as dependency --- .circleci/config.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c5d4d8247b..32401deb96 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,6 +3,12 @@ # Check https://circleci.com/docs/2.0/language-javascript/ for more details # version: 2 +dependencies: + pre: + - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + - sudo dpkg -i google-chrome.deb + - sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome + - rm google-chrome.deb jobs: build: docker: @@ -31,16 +37,6 @@ jobs: - node_modules key: v1-dependencies-root-{{ checksum "package.json" }} - - run: - name: Install Chromedriver latest version - command: | - sudo apt-get update - sudo apt-get install lsb-release - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb12 - sudo dpkg -i google-chrome.deb - sudo sed -i ‘s|HERE/chrome"|HERE/chrome" --disable-setuid-sandbox|g’ /opt/google/chrome/google-chrome - rm google-chrome.deb - - run: name: Add Gaia command: | From 7fb9b23271dd193ed7abef789547406fb4ff0a3d Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:23:59 +0000 Subject: [PATCH 23/37] more sleeps --- test/e2e/common.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/e2e/common.js b/test/e2e/common.js index 06decc2f8d..79b0c4a592 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -11,10 +11,13 @@ module.exports = { return } // close notifications as they overlay the menu button + await sleep(100) while (await client.isExisting(`.ni-notification`)) { await client.$(`.ni-notification`).click() + await sleep(100) } await client.waitForExist('.material-icons=menu', 1000) + await sleep(100) await client.$('.material-icons=menu').click() await client.waitForExist('.app-menu', 1000) }, From 50c27c13eac8eaddb03a2135081b1f826226fa17 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:31:03 +0000 Subject: [PATCH 24/37] added new chromedriver to dependencies --- .circleci/config.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 32401deb96..d17d70efb1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,12 @@ dependencies: - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - sudo dpkg -i google-chrome.deb - sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome - - rm google-chrome.deb + - rm google-chrome.deb + override: + #new chromedriver + - wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip + - unzip chromedriver_linux64.zip + - sudo cp chromedriver /usr/local/bin/chromedriver jobs: build: docker: From 3ee878e9ec875cb7520207bcbc7a483b6c9991e8 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:37:16 +0000 Subject: [PATCH 25/37] moved chrome updates in step --- .circleci/config.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index d17d70efb1..6b734b28ba 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,6 +47,20 @@ jobs: command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia sudo chmod o+wx /home/circleci/repo/gaia + + - run: + name: Update Chrome + command: | + - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + - sudo dpkg -i google-chrome.deb + - sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome + - rm google-chrome.deb + - run: + name: Update ChromeDriver + command: | + - wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip + - unzip chromedriver_linux64.zip + - sudo cp chromedriver /usr/local/bin/chromedriver - run: yarn run test - run: yarn run test:e2e From cc46491b1a63b9c7efac2edf3f4a5c503dd087a6 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:39:27 +0000 Subject: [PATCH 26/37] removed chrome update --- .circleci/config.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6b734b28ba..185c0c708e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,14 +47,6 @@ jobs: command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia sudo chmod o+wx /home/circleci/repo/gaia - - - run: - name: Update Chrome - command: | - - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - - sudo dpkg -i google-chrome.deb - - sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome - - rm google-chrome.deb - run: name: Update ChromeDriver command: | From 41bc63973fd04b1bb14d698a0312c2344447496c Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Fri, 16 Feb 2018 15:41:10 +0000 Subject: [PATCH 27/37] fixed wrong commands --- .circleci/config.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 185c0c708e..7b67af2a15 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,12 +47,20 @@ jobs: command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia sudo chmod o+wx /home/circleci/repo/gaia + + - run: + name: Update Chrome + command: | + curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + sudo dpkg -i google-chrome.deb + sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome + rm google-chrome.deb - run: name: Update ChromeDriver command: | - - wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip - - unzip chromedriver_linux64.zip - - sudo cp chromedriver /usr/local/bin/chromedriver + wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip + unzip chromedriver_linux64.zip + sudo cp chromedriver /usr/local/bin/chromedriver - run: yarn run test - run: yarn run test:e2e From db77f717de0c6306e20a5c327760e3fccf31250d Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 12:45:56 +0100 Subject: [PATCH 28/37] update chromedriver inside packages --- .circleci/config.yml | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b67af2a15..6f155aa6db 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,17 +3,6 @@ # Check https://circleci.com/docs/2.0/language-javascript/ for more details # version: 2 -dependencies: - pre: - - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - - sudo dpkg -i google-chrome.deb - - sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome - - rm google-chrome.deb - override: - #new chromedriver - - wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip - - unzip chromedriver_linux64.zip - - sudo cp chromedriver /usr/local/bin/chromedriver jobs: build: docker: @@ -48,19 +37,13 @@ jobs: sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia sudo chmod o+wx /home/circleci/repo/gaia - - run: - name: Update Chrome - command: | - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - sudo dpkg -i google-chrome.deb - sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome - rm google-chrome.deb - run: name: Update ChromeDriver command: | wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip unzip chromedriver_linux64.zip - sudo cp chromedriver /usr/local/bin/chromedriver + sudo cp chromedriver /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver + sudo chmod o+wx /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver - run: yarn run test - run: yarn run test:e2e From 328d2cae1de73d11e490de16047ad5fbc5d2616d Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 12:54:09 +0100 Subject: [PATCH 29/37] used different chromedriver version --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6f155aa6db..6dfa54bb75 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -40,7 +40,7 @@ jobs: - run: name: Update ChromeDriver command: | - wget https://chromedriver.storage.googleapis.com/2.9/chromedriver_linux64.zip + wget https://chromedriver.storage.googleapis.com/2.35/chromedriver_linux64.zip unzip chromedriver_linux64.zip sudo cp chromedriver /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver sudo chmod o+wx /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver From ee62ea8aba5f70870fbfc6eb5bfc1d1670483814 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 13:25:45 +0100 Subject: [PATCH 30/37] restarting app in between test-suits --- test/e2e/launch.js | 13 ++++++++++--- test/e2e/signin.js | 6 +++--- test/e2e/wallet.js | 10 +++++----- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/test/e2e/launch.js b/test/e2e/launch.js index b723998537..7b7bb13cda 100644 --- a/test/e2e/launch.js +++ b/test/e2e/launch.js @@ -11,7 +11,7 @@ let { newTempDir, login } = require('./common.js') let app, home, cliHome, started let binary = process.env.BINARY_PATH -module.exports = function launch (t) { +function launch (t) { if (!started) { // tape doesn't exit properly on uncaught promise rejections process.on('unhandledRejection', error => { @@ -69,8 +69,6 @@ module.exports = function launch (t) { await startApp(app) t.ok(app.isRunning(), 'app is running') - await login(app.client, 'testkey') - resolve({app, home}) }) } @@ -161,4 +159,13 @@ async function createAccount (name, seed) { reject() }) }) +} + +module.exports = { + getApp: launch, + restart: async function(app) { + console.log('restarting app') + await app.stop() + await startApp(app) + } } \ No newline at end of file diff --git a/test/e2e/signin.js b/test/e2e/signin.js index 06f36f2ed4..8bd0bbff6a 100644 --- a/test/e2e/signin.js +++ b/test/e2e/signin.js @@ -1,15 +1,15 @@ let test = require('tape-promise/tape') -let launchApp = require('./launch.js') +let { getApp, restart } = require('./launch.js') let { logout, openMenu } = require('./common.js') test('sign in', async function (t) { - let {app, home} = await launchApp(t) + let {app, home} = await getApp(t) + await restart(app) let client = app.client let el = (...args) => client.$(...args) let continueButton = () => el('.ni-btn__value=Next').$('..') t.test('agreement', async function (t) { - await logout(client) // go to login selection await client.$('i=arrow_back').$('..').click() await client.waitForExist('.ni-li-session', 1000) diff --git a/test/e2e/wallet.js b/test/e2e/wallet.js index 0f94f910c4..5dc61c6153 100644 --- a/test/e2e/wallet.js +++ b/test/e2e/wallet.js @@ -1,6 +1,6 @@ let { spawn } = require('child_process') let test = require('tape-promise/tape') -let launchApp = require('./launch.js') +let { getApp, restart } = require('./launch.js') let { navigate, newTempDir, waitForText, sleep, login, logout } = require('./common.js') let binary = process.env.BINARY_PATH @@ -21,12 +21,12 @@ function cliSendCoins (home, to, amount) { } test('wallet', async function (t) { - let {app, home} = await launchApp(t) + let {app, home} = await getApp(t) + await restart(app) + let client = app.client let $ = (...args) => client.$(...args) - - await sleep(500) - await logout(client) + await login(client, 'testkey') let balanceEl = (denom) => From 57da0f45303fae2b358424197aa17f4a5c56ef1f Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 13:25:55 +0100 Subject: [PATCH 31/37] remove unit tests for now --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6dfa54bb75..385c6b48fb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,6 +45,6 @@ jobs: sudo cp chromedriver /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver sudo chmod o+wx /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver - - run: yarn run test + # - run: yarn run test - run: yarn run test:e2e - run: bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN From 031d5f57715a853dec655c3030eb7fe8f95b9dd6 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 14:42:18 +0100 Subject: [PATCH 32/37] close notifications after send --- test/e2e/common.js | 11 +++++++---- test/e2e/wallet.js | 6 ++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/test/e2e/common.js b/test/e2e/common.js index 79b0c4a592..9469100966 100644 --- a/test/e2e/common.js +++ b/test/e2e/common.js @@ -6,16 +6,19 @@ function sleep (ms) { } module.exports = { - async openMenu (client) { - if (await client.isExisting('.app-menu')) { - return - } + async closeNotifications (client) { // close notifications as they overlay the menu button await sleep(100) while (await client.isExisting(`.ni-notification`)) { await client.$(`.ni-notification`).click() await sleep(100) } + }, + async openMenu (client) { + if (await client.isExisting('.app-menu')) { + return + } + await module.exports.closeNotifications(client) await client.waitForExist('.material-icons=menu', 1000) await sleep(100) await client.$('.material-icons=menu').click() diff --git a/test/e2e/wallet.js b/test/e2e/wallet.js index 5dc61c6153..f483e3ac00 100644 --- a/test/e2e/wallet.js +++ b/test/e2e/wallet.js @@ -1,7 +1,7 @@ let { spawn } = require('child_process') let test = require('tape-promise/tape') let { getApp, restart } = require('./launch.js') -let { navigate, newTempDir, waitForText, sleep, login, logout } = require('./common.js') +let { navigate, newTempDir, waitForText, sleep, login, logout, closeNotifications } = require('./common.js') let binary = process.env.BINARY_PATH @@ -26,7 +26,7 @@ test('wallet', async function (t) { let client = app.client let $ = (...args) => client.$(...args) - + await login(client, 'testkey') let balanceEl = (denom) => @@ -97,6 +97,8 @@ test('wallet', async function (t) { await client.waitForExist('.ni-notification', 5000) let msg = await client.$('.ni-notification .body').getText() t.ok(msg.includes('Success'), 'Send successful') + // close the notifications to have a clean setup for the next tests + await closeNotifications(client) t.end() }) From 4df96891714c3874450664529a79ba5beac07bce Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 15:02:54 +0100 Subject: [PATCH 33/37] reenable unit tests --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 385c6b48fb..6dfa54bb75 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -45,6 +45,6 @@ jobs: sudo cp chromedriver /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver sudo chmod o+wx /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver - # - run: yarn run test + - run: yarn run test - run: yarn run test:e2e - run: bash <(curl -s https://codecov.io/bash) -t $CODECOV_TOKEN From 9d92fd56836d6a0c34ee4e643e6fcd0395474ec1 Mon Sep 17 00:00:00 2001 From: Fabian Weber Date: Thu, 22 Feb 2018 15:14:31 +0100 Subject: [PATCH 34/37] remove chromedriver update --- .circleci/config.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6dfa54bb75..41a85a20f9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -36,14 +36,6 @@ jobs: command: | sudo wget https://www.dropbox.com/s/vkyuut8hnzse614/gaia-0.5.0-linux-32?dl=1 -O ~/repo/gaia sudo chmod o+wx /home/circleci/repo/gaia - - - run: - name: Update ChromeDriver - command: | - wget https://chromedriver.storage.googleapis.com/2.35/chromedriver_linux64.zip - unzip chromedriver_linux64.zip - sudo cp chromedriver /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver - sudo chmod o+wx /home/circleci/repo/node_modules/electron-chromedriver/bin/chromedriver - run: yarn run test - run: yarn run test:e2e From e99c6b484a38f208b6227d916da9b23fa5763d41 Mon Sep 17 00:00:00 2001 From: Fabian Date: Thu, 22 Feb 2018 14:35:55 +0100 Subject: [PATCH 35/37] Revert "Merge remote-tracking branch 'origin/develop' into fabo/tape-on-ci" This reverts commit 3639f2dfd19440f100fd999c166130d1353b8f05. --- CHANGELOG.md | 2 - PULL_REQUEST_TEMPLATE.md | 4 +- app/index.ejs | 13 -- app/src/main/index.js | 30 +---- app/src/network.js | 3 +- .../components/staking/LiDelegate.vue | 18 +-- .../renderer/components/staking/PageBond.vue | 38 ++---- .../components/staking/PageDelegates.vue | 3 +- app/src/renderer/lcdClient.js | 105 --------------- app/src/renderer/main.js | 17 --- app/src/renderer/node.js | 2 +- app/src/renderer/vuex/modules/delegates.js | 8 +- config.js | 7 +- package.json | 4 +- tasks/release.js | 83 +++++------- test/unit/specs/App.spec.js | 13 -- .../specs/components/staking/PageBond.spec.js | 5 - .../__snapshots__/PageBond.spec.js.snap | 4 - .../__snapshots__/PageDelegates.spec.js.snap | 8 +- test/unit/specs/lcdClient.spec.js | 125 ------------------ test/unit/specs/main.spec.js | 3 +- webpack.renderer.config.js | 3 +- yarn.lock | 72 ++++------ 23 files changed, 104 insertions(+), 466 deletions(-) delete mode 100644 app/src/renderer/lcdClient.js delete mode 100644 test/unit/specs/lcdClient.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 8342edd599..0e52599f78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,5 +57,3 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.4.3] - 2018-02-05 ### Changed * Renamed Cosmos UI to Cosmos Voyager. @nylira -* Added Google Analytics for testnet versions -* Added Sentry error reporting for testnet versions \ No newline at end of file diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 73a70e213f..a5c5776b89 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -3,8 +3,8 @@ ### Issue - -closes: ISSUE + + ### Screenshots diff --git a/app/index.ejs b/app/index.ejs index 995a4d7b2f..9f518f6bae 100644 --- a/app/index.ejs +++ b/app/index.ejs @@ -23,16 +23,3 @@ - - -<% if (htmlWebpackPlugin.options.enableAnalytics) { %> - - - -<% } %> \ No newline at end of file diff --git a/app/src/main/index.js b/app/src/main/index.js index b60f3d24cb..bfc8e41764 100644 --- a/app/src/main/index.js +++ b/app/src/main/index.js @@ -10,7 +10,6 @@ let semver = require('semver') let event = require('event-to-promise') let toml = require('toml') let axios = require('axios') -let Raven = require('raven') let pkg = require('../../../package.json') let relayServer = require('./relayServer.js') @@ -178,8 +177,6 @@ function startProcess (name, args, env) { child.on('exit', (code) => !shuttingDown && log(`${name} exited with code ${code}`)) child.on('error', function (err) { if (!(shuttingDown && err.code === 'ECONNRESET')) { - // TODO test - Raven.captureException(err) // if we throw errors here, they are not handled by the main process console.error('[Uncaught Exception] Child', name, 'produced an unhandled exception:', err) console.log('Shutting down UI') @@ -306,16 +303,15 @@ function setupLogging (root) { if (!TEST) { process.on('exit', shutdown) - // on uncaught exceptions we wait so the sentry event can be sent process.on('uncaughtException', async function (err) { - await sleep(1000) logError('[Uncaught Exception]', err) + console.error('[Uncaught Exception]', err) await shutdown() process.exit(1) }) process.on('unhandledRejection', async function (err) { - await sleep(1000) logError('[Unhandled Promise Rejection]', err) + console.error('[Unhandled Promise Rejection]', err) await shutdown() process.exit(1) }) @@ -392,21 +388,7 @@ async function reconnect (seeds) { return nodeIP } -function setupAnalytics () { - let networkIsWhitelisted = config.analytics_networks.indexOf(config.default_network) !== -1 - if (networkIsWhitelisted) { - log('Adding analytics') - } - - // only enable sending of error events in production setups and if the network is a testnet - Raven.config(networkIsWhitelisted && process.env.NODE_ENV === 'production' ? config.sentry_dsn : '', { - captureUnhandledRejections: true - }).install() -} - async function main () { - setupAnalytics() - let appVersionPath = join(root, 'app_version') let genesisPath = join(root, 'genesis.json') let configPath = join(root, 'config.toml') @@ -439,7 +421,7 @@ async function main () { // TODO: versions of the app with different data formats will need to learn how to // migrate old data throw Error(`Data was created with an incompatible app version - data=${existingVersion} app=${pkg.version}`) + data=${existingVersion} app=${pkg.version}`) } } else { throw Error(`The data directory (${root}) has missing files`) @@ -481,7 +463,7 @@ async function main () { // TODO: semver check, or exact match? if (gaiaVersion !== expectedGaiaVersion) { throw Error(`Requires gaia ${expectedGaiaVersion}, but got ${gaiaVersion}. - Please update your gaia installation or build with a newer binary.`) + Please update your gaia installation or build with a newer binary.`) } // read chainId from genesis.json @@ -497,8 +479,8 @@ async function main () { } catch (e) { throw new Error(`Can't open config.toml: ${e.message}`) } - let configTOML = toml.parse(configText) - let seeds = configTOML.p2p.seeds.split(',').filter(x => x !== '') + let config = toml.parse(configText) + let seeds = config.p2p.seeds.split(',').filter(x => x !== '') if (seeds.length === 0) { throw new Error('No seeds specified in config.toml') } diff --git a/app/src/network.js b/app/src/network.js index f7c417ca7f..0a743d5752 100644 --- a/app/src/network.js +++ b/app/src/network.js @@ -1,10 +1,9 @@ let { join } = require('path') let { readFileSync } = require('fs') -let config = require('../../config.js') // this network gets used if none is specified via the // COSMOS_NETWORK env var -let DEFAULT_NETWORK = join(__dirname, '../networks/' + config.default_network) +let DEFAULT_NETWORK = join(__dirname, '../networks/gaia-2') let networkPath = process.env.COSMOS_NETWORK || DEFAULT_NETWORK let genesisText = readFileSync(join(networkPath, 'genesis.json'), 'utf8') diff --git a/app/src/renderer/components/staking/LiDelegate.vue b/app/src/renderer/components/staking/LiDelegate.vue index 063d845571..355fb587d1 100644 --- a/app/src/renderer/components/staking/LiDelegate.vue +++ b/app/src/renderer/components/staking/LiDelegate.vue @@ -8,13 +8,11 @@ span {{ num.prettyInt(delegate.voting_power) }} .bar(:style='vpStyles') .li-delegate__value.bonded_by_you - span {{ bondedByYou }} + span {{ amountBonded }} .li-delegate__value.status span {{ delegateType }} template(v-if="userCanDelegate") - .li-delegate__value.checkbox(v-if="bondedByYou > 0") - i.material-icons lock - .li-delegate__value.checkbox#remove-from-cart(v-else-if="inCart" @click='rm(delegate)') + .li-delegate__value.checkbox#remove-from-cart(v-if="inCart" @click='rm(delegate)') i.material-icons check_box .li-delegate__value.checkbox#add-to-cart(v-else @click='add(delegate)') i.material-icons check_box_outline_blank @@ -35,12 +33,12 @@ export default { }, computed: { ...mapGetters(['shoppingCart', 'delegates', 'config', 'committedDelegations', 'user']), - bondedByYou () { + amountBonded () { return this.num.prettyInt(this.committedDelegations[this.delegate.id]) }, styles () { let value = '' - if (this.inCart || this.bondedByYou > 0) value += 'li-delegate-active ' + if (this.inCart) value += 'li-delegate-active ' if (this.delegate.isValidator) value += 'li-delegate-validator ' return value }, @@ -80,13 +78,6 @@ export default { methods: { add (delegate) { this.$store.commit('addToCart', delegate) }, rm (delegate) { this.$store.commit('removeFromCart', delegate.id) } - }, - watch: { - bondedByYou (newVal, oldVal) { - if (newVal > 0) { - this.$store.commit('addToCart', this.delegate) - } - } } } @@ -150,7 +141,6 @@ export default { &.checkbox justify-content center - cursor pointer span white-space nowrap diff --git a/app/src/renderer/components/staking/PageBond.vue b/app/src/renderer/components/staking/PageBond.vue index dbe920a44c..8ff42fc5c9 100644 --- a/app/src/renderer/components/staking/PageBond.vue +++ b/app/src/renderer/components/staking/PageBond.vue @@ -57,10 +57,7 @@ page.page-bond(title="Bond Atoms") type="number" placeholder="Atoms" step="1" - min="0" - :max="$v.fields.delegates.$each[index].atoms.$params.between.max" - v-model.number="d.atoms" - @change.native="limitMax(d, $event)") + v-model.number="d.atoms") form-msg(name="Atoms" type="required" v-if="!$v.fields.delegates.$each[index].atoms.required") @@ -152,6 +149,10 @@ export default { oldUnbondedAtoms () { return this.totalAtoms - this.oldBondedAtoms }, + // not used + // newBondedAtoms () { + // return this.fields.delegates.reduce((sum, d) => sum + (d.atoms || 0), 0) + // }, newUnbondedAtoms () { return this.fields.delegates.reduce((atoms, d) => { let delta = d.oldAtoms - d.atoms @@ -205,8 +206,8 @@ export default { this.$store.commit('activateDelegation') try { await this.$store.dispatch('submitDelegation', this.fields) - this.$store.commit('notify', { title: 'Successful Delegation', - body: 'You have successfully bonded / unbonded.' }) + this.$store.commit('notify', { title: 'Atoms Bonded', + body: 'You have successfully updated your delegations.' }) this.$router.push('/staking') } catch (err) { this.$store.commit('notifyError', { title: 'Error While Bonding Atoms', @@ -283,17 +284,14 @@ export default { restrictSize: { min: { width: offset } } }) .on('resizemove', (event) => { - this.handleResize(event.target, event.rect.width) - }) - }, - handleResize (element, width) { - let offset = this.bondBarScrubWidth - let ratio = Math.round((width - offset) / (this.bondBarOuterWidth - offset) * 100) / 100 - let rawAtoms = ratio * this.totalAtoms + let target = event.target + let ratio = (event.rect.width - offset) / (this.bondBarOuterWidth - offset) + let rawAtoms = ratio * this.totalAtoms - element.style.width = width + 'px' + target.style.width = event.rect.width + 'px' - return this.updateDelegateAtoms(element.id.split('-')[1], rawAtoms) + this.updateDelegateAtoms(target.id.split('-')[1], rawAtoms) + }) }, updateDelegateAtoms (delegateId, rawAtoms) { let d = this.fields.delegates.find(d => d.id === delegateId) @@ -303,8 +301,8 @@ export default { d.deltaAtoms = this.delta(rawAtoms, d.oldAtoms, 'int') d.deltaAtomsPercent = this.percent(this.delta(rawAtoms, d.oldAtoms), this.totalAtoms) - return d } + return d.atoms }, setBondBarOuterWidth () { let outerBar = this.$el.querySelector('.bond-bar__outer') @@ -327,14 +325,6 @@ export default { value = Math.round(ratio * 100) } return value + '%' - }, - limitMax (delegate, event) { - let max = parseInt(event.target.max) - if (delegate.atoms >= max) { - console.log(`${delegate.atoms} <= ${max}`) - delegate.atoms = max - return - } } }, async mounted () { diff --git a/app/src/renderer/components/staking/PageDelegates.vue b/app/src/renderer/components/staking/PageDelegates.vue index 0cba7c9a13..8ab7d5ee48 100644 --- a/app/src/renderer/components/staking/PageDelegates.vue +++ b/app/src/renderer/components/staking/PageDelegates.vue @@ -30,6 +30,7 @@ page(title='Validators and Candidates') @@ -121,7 +123,6 @@ export default { left 0 right 0 z-index z(toolBar) - .label color bright line-height 2rem diff --git a/app/src/renderer/lcdClient.js b/app/src/renderer/lcdClient.js deleted file mode 100644 index ae4b76654c..0000000000 --- a/app/src/renderer/lcdClient.js +++ /dev/null @@ -1,105 +0,0 @@ -'use strict' - -const axios = require('axios') - -// returns an async function which makes a request for the given -// HTTP method (GET/POST/DELETE/etc) and path (/foo/bar) -function req (method, path) { - return async function (data) { - return await this.request(method, path, data) - } -} - -// returns an async function which makes a request for the given -// HTTP method and path, which accepts arguments to be appended -// to the path (/foo/{arg}/...) -function argReq (method, path) { - return async function (args, data) { - // `args` can either be a single value or an array - if (Array.isArray(args)) { - args = args.join('/') - } - return await this.request(method, `${path}/${args}`, data) - } -} - -class Client { - constructor (server = 'http://localhost:8998') { - this.server = server - } - - async request (method, path, data) { - try { - let res = await axios[method.toLowerCase()](this.server + path, data) - return res.data - } catch (resError) { - if (!resError.response || !resError.response.data) { - throw resError - } - let data = resError.response.data - // server responded with error message, create an Error from that - let error = Error(data.error) - error.code = data.code - throw error - } - } -} - -let fetchAccount = argReq('GET', '/query/account') -let fetchNonce = argReq('GET', '/query/nonce') - -Object.assign(Client.prototype, { - sign: req('POST', '/sign'), - postTx: req('POST', '/tx'), - - // keys - generateKey: req('POST', '/keys'), - listKeys: req('GET', '/keys'), - getKey: argReq('GET', '/keys'), - updateKey: argReq('PUT', '/keys'), - deleteKey: argReq('DELETE', '/keys'), - recoverKey: req('POST', '/keys/recover'), - - // coins - buildSend: req('POST', '/build/send'), - async queryAccount (address) { - try { - return await fetchAccount.call(this, address) - } catch (err) { - // if account not found, return null instead of throwing - if (err.message.includes('account bytes are empty')) { - return null - } - throw err - } - }, - coinTxs: argReq('GET', '/tx/coin'), - - // nonce - async queryNonce (address) { - try { - return await fetchNonce.call(this, address) - } catch (err) { - // if nonce not found, return 0 instead of throwing - if (err.message.includes('nonce empty')) { - return 0 - } - throw err - } - }, - - // Tendermint RPC - status: req('GET', '/tendermint/status'), - - // staking - candidate: argReq('GET', '/query/stake/candidates'), - candidates: req('GET', '/query/stake/candidates'), - buildDelegate: req('POST', '/build/stake/delegate'), - buildUnbond: req('POST', '/build/stake/unbond'), - bondingsByDelegator: argReq('GET', '/tx/bondings/delegator'), - bondingsByValidator: argReq('GET', '/tx/bondings/validator') - - // TODO: separate API registration for different modules -}) - -module.exports = Client diff --git a/app/src/renderer/main.js b/app/src/renderer/main.js index 9454bec942..5042de94d4 100644 --- a/app/src/renderer/main.js +++ b/app/src/renderer/main.js @@ -5,33 +5,16 @@ import Router from 'vue-router' import Vuelidate from 'vuelidate' import shrinkStacktrace from '../helpers/shrink-stacktrace.js' import axios from 'axios' -import Raven from 'raven-js' -import {remote} from 'electron' - -const config = require('../../../config') import App from './App' import routes from './routes' import Node from './node' import Store from './vuex/store' -// setup sentry remote error reporting on testnets -const networkIsWhitelisted = config.analytics_networks.indexOf(config.default_network) !== -1 -Raven.config(networkIsWhitelisted && remote.getGlobal('process').env.NODE_ENV === 'production' ? config.sentry_dsn : '').install() - -// handle uncaught errors -window.addEventListener('unhandledrejection', function (event) { - Raven.captureException(event.reason) -}) -window.addEventListener('error', function (event) { - Raven.captureException(event.reason) -}) Vue.config.errorHandler = (error, vm, info) => { - Raven.captureException(error) shrinkStacktrace(error) return true } - Vue.use(Electron) Vue.use(Resource) Vue.use(Router) diff --git a/app/src/renderer/node.js b/app/src/renderer/node.js index 4699891385..dc29d7d7a0 100644 --- a/app/src/renderer/node.js +++ b/app/src/renderer/node.js @@ -1,6 +1,6 @@ 'use strict' const RpcClient = require('tendermint') -const RestClient = require('./lcdClient.js') +const RestClient = require('cosmos-sdk') module.exports = function (nodeIP, relayPort, lcdPort) { const RELAY_SERVER = 'http://localhost:' + relayPort diff --git a/app/src/renderer/vuex/modules/delegates.js b/app/src/renderer/vuex/modules/delegates.js index 2a5698faef..5ec7ba6cd6 100644 --- a/app/src/renderer/vuex/modules/delegates.js +++ b/app/src/renderer/vuex/modules/delegates.js @@ -1,5 +1,4 @@ import axios from 'axios' -import indicateValidators from 'scripts/indicateValidators' export default ({ dispatch, node }) => { const state = { @@ -25,15 +24,14 @@ export default ({ dispatch, node }) => { } const actions = { - async getDelegates ({ state, dispatch, rootState }) { + async getDelegates ({ state, dispatch }) { state.loading = true let delegatePubkeys = (await node.candidates()).data - await Promise.all(delegatePubkeys.map(pubkey => { + let delegates = await Promise.all(delegatePubkeys.map(pubkey => { return dispatch('getDelegate', pubkey) })) - state.delegates = indicateValidators(state.delegates, rootState.config.maxValidators) state.loading = false - return state.delegates + return delegates }, async getDelegate ({ commit }, pubkey) { let delegate = (await axios.get(`http://localhost:${node.relayPort}/query/stake/candidate/${pubkey.data}`)).data.data diff --git a/config.js b/config.js index eb2dffe301..04855b61b0 100644 --- a/config.js +++ b/config.js @@ -30,12 +30,7 @@ let config = { overwrite: true, platform: process.env.PLATFORM_TARGET || 'darwin,linux,win32', packageManager: 'yarn' - }, - - default_network: 'gaia-2', - analytics_networks: ['gaia-2', 'gaia-3-dev', 'gaia-3'], - google_analytics: 'UA-51029217-3', - sentry_dsn: 'https://4dee9f70a7d94cc0959a265c45902d84:cbf160384aab4cdeafbe9a08dee3b961@sentry.io/288169' + } } config.building.name = config.name diff --git a/package.json b/package.json index cb5c234869..e8a93a5372 100644 --- a/package.json +++ b/package.json @@ -96,11 +96,13 @@ "@nylira/vue-button": "^4.3.2", "@nylira/vue-field": "^1.1.17", "@nylira/vue-form-msg": "^1.0.3", + "@nylira/vue-input": "^3.2.0", "@nylira/vue-notifications": "^1.4.4", "@vue/test-utils": "^1.0.0-beta.11", "axios": "^0.17.0", "casual": "^1.5.19", "chart.js": "^2.6.0", + "cosmos-sdk": "^1.5.1", "deterministic-tar": "^0.1.2", "deterministic-zip": "^1.0.5", "electron": "^1.7.5", @@ -119,8 +121,6 @@ "no-scroll": "^2.1.0", "numeral": "^2.0.6", "perfect-scrollbar": "^1.3.0", - "raven": "^2.4.1", - "raven-js": "^3.22.3", "semver": "^5.4.1", "shortid": "^2.2.8", "stacktrace-js": "^2.0.0", diff --git a/tasks/release.js b/tasks/release.js index bb63e65632..ddd61fd143 100644 --- a/tasks/release.js +++ b/tasks/release.js @@ -124,18 +124,9 @@ function zipFolder (inDir, outDir, version) { return reject(err) } files + .filter(file => !fs.lstatSync(file).isDirectory()) .forEach(file => { - // make the zip deterministic by changing all file times - if (fs.lstatSync(file).isDirectory()) { - zip.file(path.relative(inDir, file), null, { - dir: true, - date: new Date('1993-06-16') - }) - } else { - zip.file(path.relative(inDir, file), fs.readFileSync(file), { - date: new Date('1987-08-16') - }) - } + zip.file(path.relative(inDir, file), fs.readFileSync(file), {date: new Date('1987-08-16')}) // make the zip deterministic by changing all file times }) resolve() }) @@ -151,44 +142,34 @@ function zipFolder (inDir, outDir, version) { }) } -async function tarFolder (inDir, outDir, version) { - let name = path.parse(inDir).name - let outFile = path.join(outDir, `${name}_${version}.tar.gz`) - var pack = tar.pack() +function tarFolder (inDir, outDir, version) { + return new Promise(async (resolve, reject) => { + let name = path.parse(inDir).name + let outFile = path.join(outDir, `${name}_${version}.tar.gz`) + var pack = tar.pack() - let files = glob(inDir + '/**', { sync: true }) - - // add files to tar - for (let file of files) { - try { - let stats = fs.lstatSync(file) - - let contents, linkname, type - if (stats.isDirectory()) { - continue - } else if (stats.isSymbolicLink()) { - linkname = fs.readlinkSync(file) - type = 'symlink' - } else { - contents = fs.readFileSync(file) - type = 'file' - } - await new Promise((resolve) => { - pack.entry(Object.assign({}, stats, { - name: path.relative(inDir, file), - type, - linkname - }), contents, resolve) + await new Promise((resolve) => { + glob(inDir + '/**/*', (err, files) => { + if (err) { + return reject(err) + } + // add files to tar + files + .filter(file => !fs.lstatSync(file).isDirectory()) + .forEach(file => { + try { + pack.entry({ name: path.relative(inDir, file) }, fs.readFileSync(file)) + } catch (err) { + console.error(`Couldn't pack file`, file, err) + // skip this file + } + }) + pack.finalize() + resolve() }) - } catch (err) { - console.error(`Couldn't pack file`, file, err) - // skip this file - } - } - pack.finalize() + }) - // make tar deterministic - await new Promise((resolve) => { + // make tar deterministic pack .pipe(deterministicTar()) // save tar to disc @@ -212,17 +193,17 @@ function deterministicTar () { var extract = tar.extract() .on('entry', function (header, stream, cb) { + if (header.type !== 'file') return cb() + header.mtime = header.atime = header.ctime = UNIXZERO header.uid = header.gid = 0 delete header.uname delete header.gname - if (header.type === 'file') { - stream.pipe(pack.entry(header, cb)) - } else { - pack.entry(header, cb) - } + header.mode = 0o777 + + stream.pipe(pack.entry(header, cb)) }) .on('finish', function () { pack.finalize() diff --git a/test/unit/specs/App.spec.js b/test/unit/specs/App.spec.js index 838257c607..3f96ae0d62 100644 --- a/test/unit/specs/App.spec.js +++ b/test/unit/specs/App.spec.js @@ -1,17 +1,4 @@ jest.mock('renderer/node.js', () => () => require('../helpers/node_mock')) -jest.mock('electron', () => ({ - require: jest.genMockFunction(), - match: jest.genMockFunction(), - app: jest.genMockFunction(), - remote: { - getGlobal: () => ({ - env: { - NODE_ENV: 'test' - } - }) - }, - dialog: jest.genMockFunction() -})) describe('App', () => { it('has all dependencies', async done => { diff --git a/test/unit/specs/components/staking/PageBond.spec.js b/test/unit/specs/components/staking/PageBond.spec.js index ebd2f03b6c..0df32b42d4 100644 --- a/test/unit/specs/components/staking/PageBond.spec.js +++ b/test/unit/specs/components/staking/PageBond.spec.js @@ -94,11 +94,6 @@ describe('PageBond', () => { expect(delegate.atoms).toBe(88) }) - it('only shows percent based on showing atoms', () => { - let updatedDelegate = wrapper.vm.handleResize(wrapper.vm.$el.querySelector('#delegate-pubkeyX'), 0.12) - expect(updatedDelegate.deltaAtomsPercent).toBe('100%') - }) - it('calculates delta', () => { expect(wrapper.vm.delta(100.23293423, 90.5304934)).toBe(9.70244083) expect(wrapper.vm.delta(100, 90, 'int')).toBe(10) diff --git a/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap b/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap index eba8a4932d..e29f470808 100644 --- a/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap +++ b/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap @@ -242,8 +242,6 @@ exports[`PageBond has the expected html structure 1`] = ` -
+
candidateY @@ -97,14 +97,14 @@ exports[`PageDelegates has the expected html structure 1`] = ` 0
- Validator + Candidate
check_box_outline_blank
-
+
candidateX @@ -120,7 +120,7 @@ exports[`PageDelegates has the expected html structure 1`] = ` 0
- Validator + Candidate
check_box_outline_blank diff --git a/test/unit/specs/lcdClient.spec.js b/test/unit/specs/lcdClient.spec.js deleted file mode 100644 index 775db24a2e..0000000000 --- a/test/unit/specs/lcdClient.spec.js +++ /dev/null @@ -1,125 +0,0 @@ -let axios = require('axios') -let LcdClient = require('../../../app/src/renderer/lcdClient.js') - -describe('LCD Client', () => { - let client = new LcdClient() - - it('makes a GET request with no args', async () => { - axios.get = jest.fn() - .mockReturnValueOnce(Promise.resolve({ - data: { foo: 'bar' } - })) - - let res = await client.status() - expect(res).toEqual({ foo: 'bar' }) - expect(axios.get.mock.calls[0]).toEqual([ - 'http://localhost:8998/tendermint/status', - undefined - ]) - }) - - it('makes a GET request with one arg', async () => { - axios.get = jest.fn() - .mockReturnValueOnce(Promise.resolve({ - data: { foo: 'bar' } - })) - - let res = await client.getKey('myKey') - expect(res).toEqual({ foo: 'bar' }) - expect(axios.get.mock.calls[0]).toEqual([ - 'http://localhost:8998/keys/myKey', - undefined - ]) - }) - - it('makes a GET request with multiple args', async () => { - axios.get = jest.fn() - .mockReturnValueOnce(Promise.resolve({ - data: { foo: 'bar' } - })) - - let res = await client.bondingsByDelegator([ 'foo', 'bar' ]) - expect(res).toEqual({ foo: 'bar' }) - expect(axios.get.mock.calls[0]).toEqual([ - 'http://localhost:8998/tx/bondings/delegator/foo/bar', - undefined - ]) - }) - - it('makes a POST request', async () => { - axios.post = jest.fn() - .mockReturnValueOnce(Promise.resolve({ - data: { foo: 'bar' } - })) - - let res = await client.generateKey() - expect(res).toEqual({ foo: 'bar' }) - expect(axios.post.mock.calls[0]).toEqual([ - 'http://localhost:8998/keys', - undefined - ]) - }) - - it('makes a POST request with args and data', async () => { - axios.put = jest.fn() - .mockReturnValueOnce(Promise.resolve({ - data: { foo: 'bar' } - })) - - let res = await client.updateKey('myKey', { abc: 123 }) - expect(res).toEqual({ foo: 'bar' }) - expect(axios.put.mock.calls[0]).toEqual([ - 'http://localhost:8998/keys/myKey', - { abc: 123 } - ]) - }) - - it('makes a GET request with an error', async () => { - axios.get = jest.fn() - .mockReturnValueOnce(Promise.reject({ - response: { - data: { - error: 'foo', - code: 123 - } - } - })) - - try { - await client.status() - } catch (err) { - expect(err.message).toBe('foo') - expect(err.code).toBe(123) - } - expect(axios.get.mock.calls[0]).toEqual([ - 'http://localhost:8998/tendermint/status', - undefined - ]) - }) - - it('does not throw error for empty results', async () => { - axios.get = jest.fn() - .mockReturnValueOnce(Promise.reject({ - response: { - data: { - error: 'account bytes are empty', - code: 1 - } - } - })) - let res = await client.queryAccount('address') - expect(res).toBe(null) - - axios.get = jest.fn() - .mockReturnValueOnce(Promise.reject({ - response: { - data: { - error: 'nonce empty', - code: 2 - } - } - })) - res = await client.queryNonce('address') - expect(res).toBe(0) - }) -}) diff --git a/test/unit/specs/main.spec.js b/test/unit/specs/main.spec.js index 2073258a12..fe15f67ea9 100644 --- a/test/unit/specs/main.spec.js +++ b/test/unit/specs/main.spec.js @@ -287,7 +287,8 @@ describe('Startup Process', () => { } catch (_err) { err = _err } - expect(err.message).toContain(`incompatible app version`) + expect(err.message).toBe(`Data was created with an incompatible app version + data=0.1.0 app=1.1.1`) let appVersion = fs.readFileSync(testRoot + 'app_version', 'utf8') expect(appVersion).toBe('0.1.0') diff --git a/webpack.renderer.config.js b/webpack.renderer.config.js index 83ad71f919..520697cbaf 100644 --- a/webpack.renderer.config.js +++ b/webpack.renderer.config.js @@ -90,8 +90,7 @@ let rendererConfig = { appModules: process.env.NODE_ENV !== 'production' ? path.resolve(__dirname, 'app/node_modules') : false, - styles: stylus(fs.readFileSync('./app/src/renderer/styles/index.styl', 'utf8')).import('./app/src/renderer/styles/variables.styl').render(), - enableAnalytics: process.env.NODE_ENV === 'production' && settings.analytics_networks.indexOf(settings.default_network) !== -1 + styles: stylus(fs.readFileSync('./app/src/renderer/styles/index.styl', 'utf8')).import('./app/src/renderer/styles/variables.styl').render() }), new webpack.NoEmitOnErrorsPlugin(), // warnings caused by websocket-stream, which has a server-part that is unavailable on the the client diff --git a/yarn.lock b/yarn.lock index cff2ec73ea..129d9163f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11,13 +11,17 @@ resolved "https://registry.yarnpkg.com/@nylira/vue-button/-/vue-button-4.3.2.tgz#f27b90a931a1a3b5e27736dba11dfcaa305d6ddb" "@nylira/vue-field@^1.1.17": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@nylira/vue-field/-/vue-field-1.2.3.tgz#47b5cde79bbb9d2993b4f5734304e0424734dab1" + version "1.1.17" + resolved "https://registry.yarnpkg.com/@nylira/vue-field/-/vue-field-1.1.17.tgz#a873c2d5e01b7ec664df0de71611b0fd9e066b97" "@nylira/vue-form-msg@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@nylira/vue-form-msg/-/vue-form-msg-1.0.3.tgz#257e3fcb1da345690f4fba959372b70e8abc9c20" +"@nylira/vue-input@^3.2.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@nylira/vue-input/-/vue-input-3.4.0.tgz#741346ce0613b831b756fccb253731015fa5c246" + "@nylira/vue-notifications@^1.4.4": version "1.4.4" resolved "https://registry.yarnpkg.com/@nylira/vue-notifications/-/vue-notifications-1.4.4.tgz#8ef4d3bbdbcbdf5570feaf17afd45c83c43d5496" @@ -391,6 +395,13 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" +axios@^0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d" + dependencies: + follow-redirects "^1.2.3" + is-buffer "^1.1.5" + axios@^0.17.0, axios@^0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.17.1.tgz#2d8e3e5d0bdbd7327f91bc814f5c57660f81824d" @@ -1492,10 +1503,6 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" -charenc@~0.0.1: - version "0.0.2" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - chart.js@^2.6.0: version "2.7.1" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.7.1.tgz#ae90b4aa4ff1f02decd6b1a2a8dabfd73c9f9886" @@ -1867,6 +1874,13 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" +cosmos-sdk@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/cosmos-sdk/-/cosmos-sdk-1.5.1.tgz#4f648aa7eaa781883dfa1bef9ee78b4fba299cf3" + dependencies: + axios "^0.16.2" + old "^0.2.0" + crc32-stream@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-1.0.1.tgz#ce2c5dc3bd8ffb3830f9cb47f540222c63c90fab" @@ -1938,10 +1952,6 @@ cross-unzip@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f" -crypt@~0.0.1: - version "0.0.2" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -3232,7 +3242,7 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -follow-redirects@^1.2.5: +follow-redirects@^1.2.3, follow-redirects@^1.2.5: version "1.4.1" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa" dependencies: @@ -4055,7 +4065,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-buffer@^1.1.5, is-buffer@~1.1.1: +is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -5212,14 +5222,6 @@ md5.js@^1.3.4: hash-base "^3.0.0" inherits "^2.0.1" -md5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" - dependencies: - charenc "~0.0.1" - crypt "~0.0.1" - is-buffer "~1.1.1" - mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -5789,6 +5791,12 @@ old@^0.1.3: dependencies: object-assign "^4.1.0" +old@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/old/-/old-0.2.0.tgz#ae75a9f33bae7cb3fe06312899b7ae5a73ba24ef" + dependencies: + object-assign "^4.1.0" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -6687,20 +6695,6 @@ range-parser@^1.0.3, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" -raven-js@^3.22.3: - version "3.22.3" - resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.22.3.tgz#8330dcc102b699ffbc2f48790978b997bf4d8f75" - -raven@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/raven/-/raven-2.4.1.tgz#7a6a6ff1c42d0a3892308f44c94273e7f88677fd" - dependencies: - cookie "0.3.1" - md5 "^2.2.1" - stack-trace "0.0.9" - timed-out "4.0.1" - uuid "3.0.0" - raw-body@2.3.2, raw-body@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" @@ -7591,10 +7585,6 @@ stack-generator@^2.0.1: dependencies: stackframe "^1.0.4" -stack-trace@0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" - stackframe@^1.0.3, stackframe@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" @@ -8006,7 +7996,7 @@ time-stamp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" -timed-out@4.0.1, timed-out@^4.0.0: +timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -8349,10 +8339,6 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" -uuid@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728" - uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" From 54f1516e14476bc5ce3ba1b9d8e362f1c1e831c4 Mon Sep 17 00:00:00 2001 From: Fabian Date: Thu, 22 Feb 2018 14:35:55 +0100 Subject: [PATCH 36/37] Revert "Revert "Merge remote-tracking branch 'origin/develop' into fabo/tape-on-ci"" This reverts commit e99c6b484a38f208b6227d916da9b23fa5763d41. --- CHANGELOG.md | 2 + PULL_REQUEST_TEMPLATE.md | 4 +- app/index.ejs | 13 ++ app/src/main/index.js | 30 ++++- app/src/network.js | 3 +- .../components/staking/LiDelegate.vue | 18 ++- .../renderer/components/staking/PageBond.vue | 38 ++++-- .../components/staking/PageDelegates.vue | 3 +- app/src/renderer/lcdClient.js | 105 +++++++++++++++ app/src/renderer/main.js | 17 +++ app/src/renderer/node.js | 2 +- app/src/renderer/vuex/modules/delegates.js | 8 +- config.js | 7 +- package.json | 4 +- tasks/release.js | 83 +++++++----- test/unit/specs/App.spec.js | 13 ++ .../specs/components/staking/PageBond.spec.js | 5 + .../__snapshots__/PageBond.spec.js.snap | 4 + .../__snapshots__/PageDelegates.spec.js.snap | 8 +- test/unit/specs/lcdClient.spec.js | 125 ++++++++++++++++++ test/unit/specs/main.spec.js | 3 +- webpack.renderer.config.js | 3 +- yarn.lock | 72 ++++++---- 23 files changed, 466 insertions(+), 104 deletions(-) create mode 100644 app/src/renderer/lcdClient.js create mode 100644 test/unit/specs/lcdClient.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e52599f78..8342edd599 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,3 +57,5 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.4.3] - 2018-02-05 ### Changed * Renamed Cosmos UI to Cosmos Voyager. @nylira +* Added Google Analytics for testnet versions +* Added Sentry error reporting for testnet versions \ No newline at end of file diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index a5c5776b89..73a70e213f 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -3,8 +3,8 @@ ### Issue - - + +closes: ISSUE ### Screenshots diff --git a/app/index.ejs b/app/index.ejs index 9f518f6bae..995a4d7b2f 100644 --- a/app/index.ejs +++ b/app/index.ejs @@ -23,3 +23,16 @@ + + +<% if (htmlWebpackPlugin.options.enableAnalytics) { %> + + + +<% } %> \ No newline at end of file diff --git a/app/src/main/index.js b/app/src/main/index.js index bfc8e41764..b60f3d24cb 100644 --- a/app/src/main/index.js +++ b/app/src/main/index.js @@ -10,6 +10,7 @@ let semver = require('semver') let event = require('event-to-promise') let toml = require('toml') let axios = require('axios') +let Raven = require('raven') let pkg = require('../../../package.json') let relayServer = require('./relayServer.js') @@ -177,6 +178,8 @@ function startProcess (name, args, env) { child.on('exit', (code) => !shuttingDown && log(`${name} exited with code ${code}`)) child.on('error', function (err) { if (!(shuttingDown && err.code === 'ECONNRESET')) { + // TODO test + Raven.captureException(err) // if we throw errors here, they are not handled by the main process console.error('[Uncaught Exception] Child', name, 'produced an unhandled exception:', err) console.log('Shutting down UI') @@ -303,15 +306,16 @@ function setupLogging (root) { if (!TEST) { process.on('exit', shutdown) + // on uncaught exceptions we wait so the sentry event can be sent process.on('uncaughtException', async function (err) { + await sleep(1000) logError('[Uncaught Exception]', err) - console.error('[Uncaught Exception]', err) await shutdown() process.exit(1) }) process.on('unhandledRejection', async function (err) { + await sleep(1000) logError('[Unhandled Promise Rejection]', err) - console.error('[Unhandled Promise Rejection]', err) await shutdown() process.exit(1) }) @@ -388,7 +392,21 @@ async function reconnect (seeds) { return nodeIP } +function setupAnalytics () { + let networkIsWhitelisted = config.analytics_networks.indexOf(config.default_network) !== -1 + if (networkIsWhitelisted) { + log('Adding analytics') + } + + // only enable sending of error events in production setups and if the network is a testnet + Raven.config(networkIsWhitelisted && process.env.NODE_ENV === 'production' ? config.sentry_dsn : '', { + captureUnhandledRejections: true + }).install() +} + async function main () { + setupAnalytics() + let appVersionPath = join(root, 'app_version') let genesisPath = join(root, 'genesis.json') let configPath = join(root, 'config.toml') @@ -421,7 +439,7 @@ async function main () { // TODO: versions of the app with different data formats will need to learn how to // migrate old data throw Error(`Data was created with an incompatible app version - data=${existingVersion} app=${pkg.version}`) + data=${existingVersion} app=${pkg.version}`) } } else { throw Error(`The data directory (${root}) has missing files`) @@ -463,7 +481,7 @@ async function main () { // TODO: semver check, or exact match? if (gaiaVersion !== expectedGaiaVersion) { throw Error(`Requires gaia ${expectedGaiaVersion}, but got ${gaiaVersion}. - Please update your gaia installation or build with a newer binary.`) + Please update your gaia installation or build with a newer binary.`) } // read chainId from genesis.json @@ -479,8 +497,8 @@ async function main () { } catch (e) { throw new Error(`Can't open config.toml: ${e.message}`) } - let config = toml.parse(configText) - let seeds = config.p2p.seeds.split(',').filter(x => x !== '') + let configTOML = toml.parse(configText) + let seeds = configTOML.p2p.seeds.split(',').filter(x => x !== '') if (seeds.length === 0) { throw new Error('No seeds specified in config.toml') } diff --git a/app/src/network.js b/app/src/network.js index 0a743d5752..f7c417ca7f 100644 --- a/app/src/network.js +++ b/app/src/network.js @@ -1,9 +1,10 @@ let { join } = require('path') let { readFileSync } = require('fs') +let config = require('../../config.js') // this network gets used if none is specified via the // COSMOS_NETWORK env var -let DEFAULT_NETWORK = join(__dirname, '../networks/gaia-2') +let DEFAULT_NETWORK = join(__dirname, '../networks/' + config.default_network) let networkPath = process.env.COSMOS_NETWORK || DEFAULT_NETWORK let genesisText = readFileSync(join(networkPath, 'genesis.json'), 'utf8') diff --git a/app/src/renderer/components/staking/LiDelegate.vue b/app/src/renderer/components/staking/LiDelegate.vue index 355fb587d1..063d845571 100644 --- a/app/src/renderer/components/staking/LiDelegate.vue +++ b/app/src/renderer/components/staking/LiDelegate.vue @@ -8,11 +8,13 @@ span {{ num.prettyInt(delegate.voting_power) }} .bar(:style='vpStyles') .li-delegate__value.bonded_by_you - span {{ amountBonded }} + span {{ bondedByYou }} .li-delegate__value.status span {{ delegateType }} template(v-if="userCanDelegate") - .li-delegate__value.checkbox#remove-from-cart(v-if="inCart" @click='rm(delegate)') + .li-delegate__value.checkbox(v-if="bondedByYou > 0") + i.material-icons lock + .li-delegate__value.checkbox#remove-from-cart(v-else-if="inCart" @click='rm(delegate)') i.material-icons check_box .li-delegate__value.checkbox#add-to-cart(v-else @click='add(delegate)') i.material-icons check_box_outline_blank @@ -33,12 +35,12 @@ export default { }, computed: { ...mapGetters(['shoppingCart', 'delegates', 'config', 'committedDelegations', 'user']), - amountBonded () { + bondedByYou () { return this.num.prettyInt(this.committedDelegations[this.delegate.id]) }, styles () { let value = '' - if (this.inCart) value += 'li-delegate-active ' + if (this.inCart || this.bondedByYou > 0) value += 'li-delegate-active ' if (this.delegate.isValidator) value += 'li-delegate-validator ' return value }, @@ -78,6 +80,13 @@ export default { methods: { add (delegate) { this.$store.commit('addToCart', delegate) }, rm (delegate) { this.$store.commit('removeFromCart', delegate.id) } + }, + watch: { + bondedByYou (newVal, oldVal) { + if (newVal > 0) { + this.$store.commit('addToCart', this.delegate) + } + } } } @@ -141,6 +150,7 @@ export default { &.checkbox justify-content center + cursor pointer span white-space nowrap diff --git a/app/src/renderer/components/staking/PageBond.vue b/app/src/renderer/components/staking/PageBond.vue index 8ff42fc5c9..dbe920a44c 100644 --- a/app/src/renderer/components/staking/PageBond.vue +++ b/app/src/renderer/components/staking/PageBond.vue @@ -57,7 +57,10 @@ page.page-bond(title="Bond Atoms") type="number" placeholder="Atoms" step="1" - v-model.number="d.atoms") + min="0" + :max="$v.fields.delegates.$each[index].atoms.$params.between.max" + v-model.number="d.atoms" + @change.native="limitMax(d, $event)") form-msg(name="Atoms" type="required" v-if="!$v.fields.delegates.$each[index].atoms.required") @@ -149,10 +152,6 @@ export default { oldUnbondedAtoms () { return this.totalAtoms - this.oldBondedAtoms }, - // not used - // newBondedAtoms () { - // return this.fields.delegates.reduce((sum, d) => sum + (d.atoms || 0), 0) - // }, newUnbondedAtoms () { return this.fields.delegates.reduce((atoms, d) => { let delta = d.oldAtoms - d.atoms @@ -206,8 +205,8 @@ export default { this.$store.commit('activateDelegation') try { await this.$store.dispatch('submitDelegation', this.fields) - this.$store.commit('notify', { title: 'Atoms Bonded', - body: 'You have successfully updated your delegations.' }) + this.$store.commit('notify', { title: 'Successful Delegation', + body: 'You have successfully bonded / unbonded.' }) this.$router.push('/staking') } catch (err) { this.$store.commit('notifyError', { title: 'Error While Bonding Atoms', @@ -284,14 +283,17 @@ export default { restrictSize: { min: { width: offset } } }) .on('resizemove', (event) => { - let target = event.target - let ratio = (event.rect.width - offset) / (this.bondBarOuterWidth - offset) - let rawAtoms = ratio * this.totalAtoms + this.handleResize(event.target, event.rect.width) + }) + }, + handleResize (element, width) { + let offset = this.bondBarScrubWidth + let ratio = Math.round((width - offset) / (this.bondBarOuterWidth - offset) * 100) / 100 + let rawAtoms = ratio * this.totalAtoms - target.style.width = event.rect.width + 'px' + element.style.width = width + 'px' - this.updateDelegateAtoms(target.id.split('-')[1], rawAtoms) - }) + return this.updateDelegateAtoms(element.id.split('-')[1], rawAtoms) }, updateDelegateAtoms (delegateId, rawAtoms) { let d = this.fields.delegates.find(d => d.id === delegateId) @@ -301,8 +303,8 @@ export default { d.deltaAtoms = this.delta(rawAtoms, d.oldAtoms, 'int') d.deltaAtomsPercent = this.percent(this.delta(rawAtoms, d.oldAtoms), this.totalAtoms) + return d } - return d.atoms }, setBondBarOuterWidth () { let outerBar = this.$el.querySelector('.bond-bar__outer') @@ -325,6 +327,14 @@ export default { value = Math.round(ratio * 100) } return value + '%' + }, + limitMax (delegate, event) { + let max = parseInt(event.target.max) + if (delegate.atoms >= max) { + console.log(`${delegate.atoms} <= ${max}`) + delegate.atoms = max + return + } } }, async mounted () { diff --git a/app/src/renderer/components/staking/PageDelegates.vue b/app/src/renderer/components/staking/PageDelegates.vue index 8ab7d5ee48..0cba7c9a13 100644 --- a/app/src/renderer/components/staking/PageDelegates.vue +++ b/app/src/renderer/components/staking/PageDelegates.vue @@ -30,7 +30,6 @@ page(title='Validators and Candidates') @@ -123,6 +121,7 @@ export default { left 0 right 0 z-index z(toolBar) + .label color bright line-height 2rem diff --git a/app/src/renderer/lcdClient.js b/app/src/renderer/lcdClient.js new file mode 100644 index 0000000000..ae4b76654c --- /dev/null +++ b/app/src/renderer/lcdClient.js @@ -0,0 +1,105 @@ +'use strict' + +const axios = require('axios') + +// returns an async function which makes a request for the given +// HTTP method (GET/POST/DELETE/etc) and path (/foo/bar) +function req (method, path) { + return async function (data) { + return await this.request(method, path, data) + } +} + +// returns an async function which makes a request for the given +// HTTP method and path, which accepts arguments to be appended +// to the path (/foo/{arg}/...) +function argReq (method, path) { + return async function (args, data) { + // `args` can either be a single value or an array + if (Array.isArray(args)) { + args = args.join('/') + } + return await this.request(method, `${path}/${args}`, data) + } +} + +class Client { + constructor (server = 'http://localhost:8998') { + this.server = server + } + + async request (method, path, data) { + try { + let res = await axios[method.toLowerCase()](this.server + path, data) + return res.data + } catch (resError) { + if (!resError.response || !resError.response.data) { + throw resError + } + let data = resError.response.data + // server responded with error message, create an Error from that + let error = Error(data.error) + error.code = data.code + throw error + } + } +} + +let fetchAccount = argReq('GET', '/query/account') +let fetchNonce = argReq('GET', '/query/nonce') + +Object.assign(Client.prototype, { + sign: req('POST', '/sign'), + postTx: req('POST', '/tx'), + + // keys + generateKey: req('POST', '/keys'), + listKeys: req('GET', '/keys'), + getKey: argReq('GET', '/keys'), + updateKey: argReq('PUT', '/keys'), + deleteKey: argReq('DELETE', '/keys'), + recoverKey: req('POST', '/keys/recover'), + + // coins + buildSend: req('POST', '/build/send'), + async queryAccount (address) { + try { + return await fetchAccount.call(this, address) + } catch (err) { + // if account not found, return null instead of throwing + if (err.message.includes('account bytes are empty')) { + return null + } + throw err + } + }, + coinTxs: argReq('GET', '/tx/coin'), + + // nonce + async queryNonce (address) { + try { + return await fetchNonce.call(this, address) + } catch (err) { + // if nonce not found, return 0 instead of throwing + if (err.message.includes('nonce empty')) { + return 0 + } + throw err + } + }, + + // Tendermint RPC + status: req('GET', '/tendermint/status'), + + // staking + candidate: argReq('GET', '/query/stake/candidates'), + candidates: req('GET', '/query/stake/candidates'), + buildDelegate: req('POST', '/build/stake/delegate'), + buildUnbond: req('POST', '/build/stake/unbond'), + bondingsByDelegator: argReq('GET', '/tx/bondings/delegator'), + bondingsByValidator: argReq('GET', '/tx/bondings/validator') + + // TODO: separate API registration for different modules +}) + +module.exports = Client diff --git a/app/src/renderer/main.js b/app/src/renderer/main.js index 5042de94d4..9454bec942 100644 --- a/app/src/renderer/main.js +++ b/app/src/renderer/main.js @@ -5,16 +5,33 @@ import Router from 'vue-router' import Vuelidate from 'vuelidate' import shrinkStacktrace from '../helpers/shrink-stacktrace.js' import axios from 'axios' +import Raven from 'raven-js' +import {remote} from 'electron' + +const config = require('../../../config') import App from './App' import routes from './routes' import Node from './node' import Store from './vuex/store' +// setup sentry remote error reporting on testnets +const networkIsWhitelisted = config.analytics_networks.indexOf(config.default_network) !== -1 +Raven.config(networkIsWhitelisted && remote.getGlobal('process').env.NODE_ENV === 'production' ? config.sentry_dsn : '').install() + +// handle uncaught errors +window.addEventListener('unhandledrejection', function (event) { + Raven.captureException(event.reason) +}) +window.addEventListener('error', function (event) { + Raven.captureException(event.reason) +}) Vue.config.errorHandler = (error, vm, info) => { + Raven.captureException(error) shrinkStacktrace(error) return true } + Vue.use(Electron) Vue.use(Resource) Vue.use(Router) diff --git a/app/src/renderer/node.js b/app/src/renderer/node.js index dc29d7d7a0..4699891385 100644 --- a/app/src/renderer/node.js +++ b/app/src/renderer/node.js @@ -1,6 +1,6 @@ 'use strict' const RpcClient = require('tendermint') -const RestClient = require('cosmos-sdk') +const RestClient = require('./lcdClient.js') module.exports = function (nodeIP, relayPort, lcdPort) { const RELAY_SERVER = 'http://localhost:' + relayPort diff --git a/app/src/renderer/vuex/modules/delegates.js b/app/src/renderer/vuex/modules/delegates.js index 5ec7ba6cd6..2a5698faef 100644 --- a/app/src/renderer/vuex/modules/delegates.js +++ b/app/src/renderer/vuex/modules/delegates.js @@ -1,4 +1,5 @@ import axios from 'axios' +import indicateValidators from 'scripts/indicateValidators' export default ({ dispatch, node }) => { const state = { @@ -24,14 +25,15 @@ export default ({ dispatch, node }) => { } const actions = { - async getDelegates ({ state, dispatch }) { + async getDelegates ({ state, dispatch, rootState }) { state.loading = true let delegatePubkeys = (await node.candidates()).data - let delegates = await Promise.all(delegatePubkeys.map(pubkey => { + await Promise.all(delegatePubkeys.map(pubkey => { return dispatch('getDelegate', pubkey) })) + state.delegates = indicateValidators(state.delegates, rootState.config.maxValidators) state.loading = false - return delegates + return state.delegates }, async getDelegate ({ commit }, pubkey) { let delegate = (await axios.get(`http://localhost:${node.relayPort}/query/stake/candidate/${pubkey.data}`)).data.data diff --git a/config.js b/config.js index 04855b61b0..eb2dffe301 100644 --- a/config.js +++ b/config.js @@ -30,7 +30,12 @@ let config = { overwrite: true, platform: process.env.PLATFORM_TARGET || 'darwin,linux,win32', packageManager: 'yarn' - } + }, + + default_network: 'gaia-2', + analytics_networks: ['gaia-2', 'gaia-3-dev', 'gaia-3'], + google_analytics: 'UA-51029217-3', + sentry_dsn: 'https://4dee9f70a7d94cc0959a265c45902d84:cbf160384aab4cdeafbe9a08dee3b961@sentry.io/288169' } config.building.name = config.name diff --git a/package.json b/package.json index e8a93a5372..cb5c234869 100644 --- a/package.json +++ b/package.json @@ -96,13 +96,11 @@ "@nylira/vue-button": "^4.3.2", "@nylira/vue-field": "^1.1.17", "@nylira/vue-form-msg": "^1.0.3", - "@nylira/vue-input": "^3.2.0", "@nylira/vue-notifications": "^1.4.4", "@vue/test-utils": "^1.0.0-beta.11", "axios": "^0.17.0", "casual": "^1.5.19", "chart.js": "^2.6.0", - "cosmos-sdk": "^1.5.1", "deterministic-tar": "^0.1.2", "deterministic-zip": "^1.0.5", "electron": "^1.7.5", @@ -121,6 +119,8 @@ "no-scroll": "^2.1.0", "numeral": "^2.0.6", "perfect-scrollbar": "^1.3.0", + "raven": "^2.4.1", + "raven-js": "^3.22.3", "semver": "^5.4.1", "shortid": "^2.2.8", "stacktrace-js": "^2.0.0", diff --git a/tasks/release.js b/tasks/release.js index ddd61fd143..bb63e65632 100644 --- a/tasks/release.js +++ b/tasks/release.js @@ -124,9 +124,18 @@ function zipFolder (inDir, outDir, version) { return reject(err) } files - .filter(file => !fs.lstatSync(file).isDirectory()) .forEach(file => { - zip.file(path.relative(inDir, file), fs.readFileSync(file), {date: new Date('1987-08-16')}) // make the zip deterministic by changing all file times + // make the zip deterministic by changing all file times + if (fs.lstatSync(file).isDirectory()) { + zip.file(path.relative(inDir, file), null, { + dir: true, + date: new Date('1993-06-16') + }) + } else { + zip.file(path.relative(inDir, file), fs.readFileSync(file), { + date: new Date('1987-08-16') + }) + } }) resolve() }) @@ -142,34 +151,44 @@ function zipFolder (inDir, outDir, version) { }) } -function tarFolder (inDir, outDir, version) { - return new Promise(async (resolve, reject) => { - let name = path.parse(inDir).name - let outFile = path.join(outDir, `${name}_${version}.tar.gz`) - var pack = tar.pack() +async function tarFolder (inDir, outDir, version) { + let name = path.parse(inDir).name + let outFile = path.join(outDir, `${name}_${version}.tar.gz`) + var pack = tar.pack() - await new Promise((resolve) => { - glob(inDir + '/**/*', (err, files) => { - if (err) { - return reject(err) - } - // add files to tar - files - .filter(file => !fs.lstatSync(file).isDirectory()) - .forEach(file => { - try { - pack.entry({ name: path.relative(inDir, file) }, fs.readFileSync(file)) - } catch (err) { - console.error(`Couldn't pack file`, file, err) - // skip this file - } - }) - pack.finalize() - resolve() + let files = glob(inDir + '/**', { sync: true }) + + // add files to tar + for (let file of files) { + try { + let stats = fs.lstatSync(file) + + let contents, linkname, type + if (stats.isDirectory()) { + continue + } else if (stats.isSymbolicLink()) { + linkname = fs.readlinkSync(file) + type = 'symlink' + } else { + contents = fs.readFileSync(file) + type = 'file' + } + await new Promise((resolve) => { + pack.entry(Object.assign({}, stats, { + name: path.relative(inDir, file), + type, + linkname + }), contents, resolve) }) - }) + } catch (err) { + console.error(`Couldn't pack file`, file, err) + // skip this file + } + } + pack.finalize() - // make tar deterministic + // make tar deterministic + await new Promise((resolve) => { pack .pipe(deterministicTar()) // save tar to disc @@ -193,17 +212,17 @@ function deterministicTar () { var extract = tar.extract() .on('entry', function (header, stream, cb) { - if (header.type !== 'file') return cb() - header.mtime = header.atime = header.ctime = UNIXZERO header.uid = header.gid = 0 delete header.uname delete header.gname - header.mode = 0o777 - - stream.pipe(pack.entry(header, cb)) + if (header.type === 'file') { + stream.pipe(pack.entry(header, cb)) + } else { + pack.entry(header, cb) + } }) .on('finish', function () { pack.finalize() diff --git a/test/unit/specs/App.spec.js b/test/unit/specs/App.spec.js index 3f96ae0d62..838257c607 100644 --- a/test/unit/specs/App.spec.js +++ b/test/unit/specs/App.spec.js @@ -1,4 +1,17 @@ jest.mock('renderer/node.js', () => () => require('../helpers/node_mock')) +jest.mock('electron', () => ({ + require: jest.genMockFunction(), + match: jest.genMockFunction(), + app: jest.genMockFunction(), + remote: { + getGlobal: () => ({ + env: { + NODE_ENV: 'test' + } + }) + }, + dialog: jest.genMockFunction() +})) describe('App', () => { it('has all dependencies', async done => { diff --git a/test/unit/specs/components/staking/PageBond.spec.js b/test/unit/specs/components/staking/PageBond.spec.js index 0df32b42d4..ebd2f03b6c 100644 --- a/test/unit/specs/components/staking/PageBond.spec.js +++ b/test/unit/specs/components/staking/PageBond.spec.js @@ -94,6 +94,11 @@ describe('PageBond', () => { expect(delegate.atoms).toBe(88) }) + it('only shows percent based on showing atoms', () => { + let updatedDelegate = wrapper.vm.handleResize(wrapper.vm.$el.querySelector('#delegate-pubkeyX'), 0.12) + expect(updatedDelegate.deltaAtomsPercent).toBe('100%') + }) + it('calculates delta', () => { expect(wrapper.vm.delta(100.23293423, 90.5304934)).toBe(9.70244083) expect(wrapper.vm.delta(100, 90, 'int')).toBe(10) diff --git a/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap b/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap index e29f470808..eba8a4932d 100644 --- a/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap +++ b/test/unit/specs/components/staking/__snapshots__/PageBond.spec.js.snap @@ -242,6 +242,8 @@ exports[`PageBond has the expected html structure 1`] = `
-
+
candidateY @@ -97,14 +97,14 @@ exports[`PageDelegates has the expected html structure 1`] = ` 0
- Candidate + Validator
check_box_outline_blank
-
+
candidateX @@ -120,7 +120,7 @@ exports[`PageDelegates has the expected html structure 1`] = ` 0
- Candidate + Validator
check_box_outline_blank diff --git a/test/unit/specs/lcdClient.spec.js b/test/unit/specs/lcdClient.spec.js new file mode 100644 index 0000000000..775db24a2e --- /dev/null +++ b/test/unit/specs/lcdClient.spec.js @@ -0,0 +1,125 @@ +let axios = require('axios') +let LcdClient = require('../../../app/src/renderer/lcdClient.js') + +describe('LCD Client', () => { + let client = new LcdClient() + + it('makes a GET request with no args', async () => { + axios.get = jest.fn() + .mockReturnValueOnce(Promise.resolve({ + data: { foo: 'bar' } + })) + + let res = await client.status() + expect(res).toEqual({ foo: 'bar' }) + expect(axios.get.mock.calls[0]).toEqual([ + 'http://localhost:8998/tendermint/status', + undefined + ]) + }) + + it('makes a GET request with one arg', async () => { + axios.get = jest.fn() + .mockReturnValueOnce(Promise.resolve({ + data: { foo: 'bar' } + })) + + let res = await client.getKey('myKey') + expect(res).toEqual({ foo: 'bar' }) + expect(axios.get.mock.calls[0]).toEqual([ + 'http://localhost:8998/keys/myKey', + undefined + ]) + }) + + it('makes a GET request with multiple args', async () => { + axios.get = jest.fn() + .mockReturnValueOnce(Promise.resolve({ + data: { foo: 'bar' } + })) + + let res = await client.bondingsByDelegator([ 'foo', 'bar' ]) + expect(res).toEqual({ foo: 'bar' }) + expect(axios.get.mock.calls[0]).toEqual([ + 'http://localhost:8998/tx/bondings/delegator/foo/bar', + undefined + ]) + }) + + it('makes a POST request', async () => { + axios.post = jest.fn() + .mockReturnValueOnce(Promise.resolve({ + data: { foo: 'bar' } + })) + + let res = await client.generateKey() + expect(res).toEqual({ foo: 'bar' }) + expect(axios.post.mock.calls[0]).toEqual([ + 'http://localhost:8998/keys', + undefined + ]) + }) + + it('makes a POST request with args and data', async () => { + axios.put = jest.fn() + .mockReturnValueOnce(Promise.resolve({ + data: { foo: 'bar' } + })) + + let res = await client.updateKey('myKey', { abc: 123 }) + expect(res).toEqual({ foo: 'bar' }) + expect(axios.put.mock.calls[0]).toEqual([ + 'http://localhost:8998/keys/myKey', + { abc: 123 } + ]) + }) + + it('makes a GET request with an error', async () => { + axios.get = jest.fn() + .mockReturnValueOnce(Promise.reject({ + response: { + data: { + error: 'foo', + code: 123 + } + } + })) + + try { + await client.status() + } catch (err) { + expect(err.message).toBe('foo') + expect(err.code).toBe(123) + } + expect(axios.get.mock.calls[0]).toEqual([ + 'http://localhost:8998/tendermint/status', + undefined + ]) + }) + + it('does not throw error for empty results', async () => { + axios.get = jest.fn() + .mockReturnValueOnce(Promise.reject({ + response: { + data: { + error: 'account bytes are empty', + code: 1 + } + } + })) + let res = await client.queryAccount('address') + expect(res).toBe(null) + + axios.get = jest.fn() + .mockReturnValueOnce(Promise.reject({ + response: { + data: { + error: 'nonce empty', + code: 2 + } + } + })) + res = await client.queryNonce('address') + expect(res).toBe(0) + }) +}) diff --git a/test/unit/specs/main.spec.js b/test/unit/specs/main.spec.js index fe15f67ea9..2073258a12 100644 --- a/test/unit/specs/main.spec.js +++ b/test/unit/specs/main.spec.js @@ -287,8 +287,7 @@ describe('Startup Process', () => { } catch (_err) { err = _err } - expect(err.message).toBe(`Data was created with an incompatible app version - data=0.1.0 app=1.1.1`) + expect(err.message).toContain(`incompatible app version`) let appVersion = fs.readFileSync(testRoot + 'app_version', 'utf8') expect(appVersion).toBe('0.1.0') diff --git a/webpack.renderer.config.js b/webpack.renderer.config.js index 520697cbaf..83ad71f919 100644 --- a/webpack.renderer.config.js +++ b/webpack.renderer.config.js @@ -90,7 +90,8 @@ let rendererConfig = { appModules: process.env.NODE_ENV !== 'production' ? path.resolve(__dirname, 'app/node_modules') : false, - styles: stylus(fs.readFileSync('./app/src/renderer/styles/index.styl', 'utf8')).import('./app/src/renderer/styles/variables.styl').render() + styles: stylus(fs.readFileSync('./app/src/renderer/styles/index.styl', 'utf8')).import('./app/src/renderer/styles/variables.styl').render(), + enableAnalytics: process.env.NODE_ENV === 'production' && settings.analytics_networks.indexOf(settings.default_network) !== -1 }), new webpack.NoEmitOnErrorsPlugin(), // warnings caused by websocket-stream, which has a server-part that is unavailable on the the client diff --git a/yarn.lock b/yarn.lock index 129d9163f7..cff2ec73ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11,17 +11,13 @@ resolved "https://registry.yarnpkg.com/@nylira/vue-button/-/vue-button-4.3.2.tgz#f27b90a931a1a3b5e27736dba11dfcaa305d6ddb" "@nylira/vue-field@^1.1.17": - version "1.1.17" - resolved "https://registry.yarnpkg.com/@nylira/vue-field/-/vue-field-1.1.17.tgz#a873c2d5e01b7ec664df0de71611b0fd9e066b97" + version "1.2.3" + resolved "https://registry.yarnpkg.com/@nylira/vue-field/-/vue-field-1.2.3.tgz#47b5cde79bbb9d2993b4f5734304e0424734dab1" "@nylira/vue-form-msg@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@nylira/vue-form-msg/-/vue-form-msg-1.0.3.tgz#257e3fcb1da345690f4fba959372b70e8abc9c20" -"@nylira/vue-input@^3.2.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@nylira/vue-input/-/vue-input-3.4.0.tgz#741346ce0613b831b756fccb253731015fa5c246" - "@nylira/vue-notifications@^1.4.4": version "1.4.4" resolved "https://registry.yarnpkg.com/@nylira/vue-notifications/-/vue-notifications-1.4.4.tgz#8ef4d3bbdbcbdf5570feaf17afd45c83c43d5496" @@ -395,13 +391,6 @@ aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -axios@^0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d" - dependencies: - follow-redirects "^1.2.3" - is-buffer "^1.1.5" - axios@^0.17.0, axios@^0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.17.1.tgz#2d8e3e5d0bdbd7327f91bc814f5c57660f81824d" @@ -1503,6 +1492,10 @@ chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + chart.js@^2.6.0: version "2.7.1" resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.7.1.tgz#ae90b4aa4ff1f02decd6b1a2a8dabfd73c9f9886" @@ -1874,13 +1867,6 @@ cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: parse-json "^2.2.0" require-from-string "^1.1.0" -cosmos-sdk@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/cosmos-sdk/-/cosmos-sdk-1.5.1.tgz#4f648aa7eaa781883dfa1bef9ee78b4fba299cf3" - dependencies: - axios "^0.16.2" - old "^0.2.0" - crc32-stream@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-1.0.1.tgz#ce2c5dc3bd8ffb3830f9cb47f540222c63c90fab" @@ -1952,6 +1938,10 @@ cross-unzip@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f" +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -3242,7 +3232,7 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -follow-redirects@^1.2.3, follow-redirects@^1.2.5: +follow-redirects@^1.2.5: version "1.4.1" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa" dependencies: @@ -4065,7 +4055,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-buffer@^1.1.5: +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -5222,6 +5212,14 @@ md5.js@^1.3.4: hash-base "^3.0.0" inherits "^2.0.1" +md5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + mdurl@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -5791,12 +5789,6 @@ old@^0.1.3: dependencies: object-assign "^4.1.0" -old@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/old/-/old-0.2.0.tgz#ae75a9f33bae7cb3fe06312899b7ae5a73ba24ef" - dependencies: - object-assign "^4.1.0" - on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -6695,6 +6687,20 @@ range-parser@^1.0.3, range-parser@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" +raven-js@^3.22.3: + version "3.22.3" + resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.22.3.tgz#8330dcc102b699ffbc2f48790978b997bf4d8f75" + +raven@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raven/-/raven-2.4.1.tgz#7a6a6ff1c42d0a3892308f44c94273e7f88677fd" + dependencies: + cookie "0.3.1" + md5 "^2.2.1" + stack-trace "0.0.9" + timed-out "4.0.1" + uuid "3.0.0" + raw-body@2.3.2, raw-body@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" @@ -7585,6 +7591,10 @@ stack-generator@^2.0.1: dependencies: stackframe "^1.0.4" +stack-trace@0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" + stackframe@^1.0.3, stackframe@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b" @@ -7996,7 +8006,7 @@ time-stamp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" -timed-out@^4.0.0: +timed-out@4.0.1, timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -8339,6 +8349,10 @@ utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" +uuid@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728" + uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" From 5e48362657334792b2fc94552a81e314ae6b5789 Mon Sep 17 00:00:00 2001 From: Fabian Date: Thu, 22 Feb 2018 16:38:11 +0100 Subject: [PATCH 37/37] define enable analtics as a env variable so we can switch if off in test --- README.md | 2 +- app/src/main/index.js | 32 ++++++++++++++------------------ app/src/renderer/main.js | 6 +++--- config.js | 3 ++- package.json | 4 ++-- test/e2e/launch.js | 3 +-- test/unit/specs/main.spec.js | 3 ++- webpack.main.config.js | 4 +++- webpack.renderer.config.js | 4 +++- 9 files changed, 31 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 964faaaefe..9f81e03c58 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ A list of all environment variables and their purpose: |NODE_ENV|'production', 'development'||| |LOGGING|'true', 'false'|'true'|Disable logging| |MOCK|'true', 'false'|'true' in development|Mock data to receive from the chain| -|COSMOS_TEST|'true', 'false'|'false'|Disable code that influences unit tests, like logging to files| +|COSMOS_ANALYTICS|'true', 'false'|'false'|Disable code that should not run in e2e tests, like crash reporting| |COSMOS_NETWORK|{path to network configuration folder}|'../networks/gaia-1'|Network to connect to| |COSMOS_HOME|{path to config persistence folder}|'$HOME/voyager[-dev]'|| |COSMOS_NODE|{ip of a certain node}||Node to connect to| diff --git a/app/src/main/index.js b/app/src/main/index.js index b60f3d24cb..12072cf9b3 100644 --- a/app/src/main/index.js +++ b/app/src/main/index.js @@ -31,10 +31,10 @@ const networkPath = require('../network.js').path const baseserverHome = join(root, 'baseserver') const WIN = /^win/.test(process.platform) const DEV = process.env.NODE_ENV === 'development' -const TEST = JSON.parse(process.env.COSMOS_TEST || 'false') !== false +const TEST = process.env.NODE_ENV === 'testing' // TODO default logging or default disable logging? const LOGGING = JSON.parse(process.env.LOGGING || 'true') !== false -const MOCK = JSON.parse(process.env.MOCK || !TEST && DEV) !== false +const MOCK = JSON.parse(process.env.MOCK || DEV) !== false const winURL = DEV ? `http://localhost:${config.wds_port}` : `file://${__dirname}/index.html` @@ -58,7 +58,7 @@ function logError (...args) { function logProcess (process, logPath) { fs.ensureFileSync(logPath) // Writestreams are blocking fs cleanup in tests, if you get errors, disable logging - if (LOGGING && !TEST) { + if (LOGGING) { let logStream = fs.createWriteStream(logPath, { flags: 'a' // 'a' means appending (old data will be preserved) }) @@ -154,7 +154,7 @@ function startProcess (name, args, env) { if (process.env.BINARY_PATH) { binPath = process.env.BINARY_PATH } else - if (DEV || TEST) { + if (DEV) { // in dev mode or tests, use binaries installed in GOPATH let GOPATH = process.env.GOPATH if (!GOPATH) GOPATH = join(home, 'go') @@ -269,7 +269,7 @@ async function initBaseserver (chainId, home, node) { * log to file */ function setupLogging (root) { - if (TEST) return + if (!LOGGING) return // initialize log file let logFilePath = join(root, 'main.log') @@ -286,21 +286,17 @@ function setupLogging (root) { // TODO overwriting console.log sounds like a bad idea, can we find an alternative? // eslint-disable-next-line no-func-assign log = function (...args) { - if (LOGGING) { - if (DEV) { - console.log(...args) - } - mainLog.write(`main-process: ${args.join(' ')}\r\n`) + if (DEV) { + console.log(...args) } + mainLog.write(`main-process: ${args.join(' ')}\r\n`) } // eslint-disable-next-line no-func-assign logError = function (...args) { - if (LOGGING) { - if (DEV) { - console.error(...args) - } - mainLog.write(`main-process: ${args.join(' ')}\r\n`) + if (DEV) { + console.error(...args) } + mainLog.write(`main-process: ${args.join(' ')}\r\n`) } } @@ -393,13 +389,13 @@ async function reconnect (seeds) { } function setupAnalytics () { - let networkIsWhitelisted = config.analytics_networks.indexOf(config.default_network) !== -1 - if (networkIsWhitelisted) { + let analyticsEnabled = JSON.parse(process.env.COSMOS_ANALYTICS || 'false') + if (analyticsEnabled) { log('Adding analytics') } // only enable sending of error events in production setups and if the network is a testnet - Raven.config(networkIsWhitelisted && process.env.NODE_ENV === 'production' ? config.sentry_dsn : '', { + Raven.config(analyticsEnabled ? config.sentry_dsn : '', { captureUnhandledRejections: true }).install() } diff --git a/app/src/renderer/main.js b/app/src/renderer/main.js index 9454bec942..9beb1e9869 100644 --- a/app/src/renderer/main.js +++ b/app/src/renderer/main.js @@ -15,9 +15,9 @@ import routes from './routes' import Node from './node' import Store from './vuex/store' -// setup sentry remote error reporting on testnets -const networkIsWhitelisted = config.analytics_networks.indexOf(config.default_network) !== -1 -Raven.config(networkIsWhitelisted && remote.getGlobal('process').env.NODE_ENV === 'production' ? config.sentry_dsn : '').install() +// setup sentry remote error reporting +const analyticsEnabled = JSON.parse(remote.getGlobal('process').env.COSMOS_ANALYTICS || 'false') +Raven.config(analyticsEnabled ? config.sentry_dsn_public : '').install() // handle uncaught errors window.addEventListener('unhandledrejection', function (event) { diff --git a/config.js b/config.js index eb2dffe301..760f9598d0 100644 --- a/config.js +++ b/config.js @@ -35,7 +35,8 @@ let config = { default_network: 'gaia-2', analytics_networks: ['gaia-2', 'gaia-3-dev', 'gaia-3'], google_analytics: 'UA-51029217-3', - sentry_dsn: 'https://4dee9f70a7d94cc0959a265c45902d84:cbf160384aab4cdeafbe9a08dee3b961@sentry.io/288169' + sentry_dsn: 'https://4dee9f70a7d94cc0959a265c45902d84:cbf160384aab4cdeafbe9a08dee3b961@sentry.io/288169', + sentry_dsn_public: 'https://4dee9f70a7d94cc0959a265c45902d84@sentry.io/288169' } config.building.name = config.name diff --git a/package.json b/package.json index cb5c234869..918d5692f8 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "pack:main": "cross-env NODE_ENV=production webpack --colors --config webpack.main.config.js", "pack:renderer": "cross-env NODE_ENV=production webpack --colors --config webpack.renderer.config.js", "test": "yarn run lint && yarn run test:unit", - "test:unit": "cross-env LOGGING=false MOCK=false jest --maxWorkers=2", - "test:e2e": "yarn run pack && tape \"test/e2e/*.js\"", + "test:unit": "cross-env LOGGING=false MOCK=false ANALYTICS=false NODE_ENV=testing jest --maxWorkers=2", + "test:e2e": "cross-env ANALYTICS=false yarn run pack && tape \"test/e2e/*.js\"", "test:exe": "node tasks/test-build.js", "test:coverage": "http-server test/unit/coverage/lcov-report", "vue:route": "node tasks/vue/route.js", diff --git a/test/e2e/launch.js b/test/e2e/launch.js index 7b7bb13cda..4763a88d8e 100644 --- a/test/e2e/launch.js +++ b/test/e2e/launch.js @@ -41,8 +41,7 @@ function launch (t) { startTimeout: 10000, waitTimeout: 10000, env: { - // COSMOS_UI_ONLY: 'true', - // COSMOS_TEST: 'true', + ANALYTICS: 'false', COSMOS_NODE: 'localhost', NODE_ENV: 'production', PREVIEW: 'true', diff --git a/test/unit/specs/main.spec.js b/test/unit/specs/main.spec.js index 2073258a12..6f84413f6e 100644 --- a/test/unit/specs/main.spec.js +++ b/test/unit/specs/main.spec.js @@ -54,7 +54,8 @@ let childProcess describe('Startup Process', () => { Object.assign(process.env, { - COSMOS_TEST: true, + ANALYTICS: false, + LOGGING: false, COSMOS_NETWORK: 'app/networks/gaia-2', COSMOS_HOME: testRoot }) diff --git a/webpack.main.config.js b/webpack.main.config.js index d0970631e0..624c8dcd9d 100644 --- a/webpack.main.config.js +++ b/webpack.main.config.js @@ -4,6 +4,7 @@ process.env.BABEL_ENV = 'main' const path = require('path') const webpack = require('webpack') +const settings = require('./config.js') let mainConfig = { entry: { @@ -38,7 +39,8 @@ let mainConfig = { plugins: [ new webpack.NoEmitOnErrorsPlugin(), new webpack.DefinePlugin({ - 'process.env.NODE_ENV': '"production"' + 'process.env.NODE_ENV': '"production"', + 'process.env.COSMOS_ANALYTICS': '"' + (process.env.COSMOS_ANALYTICS || process.env.NODE_ENV === 'production' && settings.analytics_networks.indexOf(settings.default_network) !== -1) + '"' }) ], resolve: { diff --git a/webpack.renderer.config.js b/webpack.renderer.config.js index 83ad71f919..bb8f258405 100644 --- a/webpack.renderer.config.js +++ b/webpack.renderer.config.js @@ -15,6 +15,8 @@ function resolve (dir) { return path.join(__dirname, dir) } +process.env.COSMOS_ANALYTICS = (process.env.COSMOS_ANALYTICS || process.env.NODE_ENV === 'production' && settings.analytics_networks.indexOf(settings.default_network) !== -1) + '' + let rendererConfig = { devtool: '#eval-source-map', entry: { @@ -91,7 +93,7 @@ let rendererConfig = { ? path.resolve(__dirname, 'app/node_modules') : false, styles: stylus(fs.readFileSync('./app/src/renderer/styles/index.styl', 'utf8')).import('./app/src/renderer/styles/variables.styl').render(), - enableAnalytics: process.env.NODE_ENV === 'production' && settings.analytics_networks.indexOf(settings.default_network) !== -1 + enableAnalytics: JSON.parse(process.env.COSMOS_ANALYTICS || 'false') }), new webpack.NoEmitOnErrorsPlugin(), // warnings caused by websocket-stream, which has a server-part that is unavailable on the the client