Arnaud97234
6 years ago
12 changed files with 172 additions and 2 deletions
@ -0,0 +1,15 @@ |
|||
# ledgerLive-QA |
|||
Automated tests for Ledger Live Desktop application. |
|||
Start Ledger Live Desktop application with accounts for the supported coin. Operations history removed from db. Then sync to retrieve account balance and transactions history. |
|||
|
|||
|
|||
## Accounts setup and sync |
|||
#### Launch test |
|||
yarn test-sync |
|||
|
|||
#### Test description |
|||
Clean Ledger Live Application settings directory. |
|||
Copy app.json init file for testing in a new Ledger Live Application settings directory. |
|||
Start Ledger Live Desktop app. |
|||
Wait for sync OK. |
|||
Compare new app.json with expected app.json file. |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,49 @@ |
|||
#!/bin/bash |
|||
|
|||
# get app version |
|||
ledgerLiveVersion=$(grep version package.json | cut -d : -f 2 | sed -E 's/.*"([^"]*)".*/\1/g') |
|||
|
|||
# OS settings |
|||
if [[ $(uname) == 'Darwin' ]]; then \ |
|||
settingsPath=~/Library/Application\ Support/Ledger\ Live/ |
|||
appPath="/Applications/Ledger Live.app/Contents/MacOS/Ledger Live" |
|||
elif [[ $(uname) == 'Linux' ]]; then \ |
|||
settingsPath="$HOME/.config/Ledger Live" |
|||
appPath="$HOME/apps/ledger-live-desktop-$ledgerLiveVersion-linux-x86_64.AppImage" |
|||
else \ |
|||
settingsPath="%AppData\\Roaming\\Ledger Live" |
|||
appPath="C:\\Program Files\\Ledger Live\\Ledger Live.exe" |
|||
fi |
|||
|
|||
# clean Ledger Live Application settings directory |
|||
rm -rf "$settingsPath" |
|||
mkdir "$settingsPath" |
|||
|
|||
# rm ../data/actual_app.json |
|||
|
|||
# Copy app.json init file for testing |
|||
cp test-e2e/sync/data/empty-app.json "$settingsPath/app.json" |
|||
|
|||
# Start Ledger Live Desktop app |
|||
"$appPath" & |
|||
lastPid=$! |
|||
|
|||
# wait for sync |
|||
electron ./test-e2e/sync/wait-sync.js |
|||
returnCode=$? |
|||
|
|||
# kill Ledger Live Desktop process |
|||
kill -9 $lastPid |
|||
|
|||
if [[ $returnCode = 0 ]]; then |
|||
echo "[OK] Sync finished" |
|||
else |
|||
echo "[x] Sync failed" |
|||
exit 1 |
|||
fi |
|||
|
|||
# Copy app.json file to test folder |
|||
cp "$settingsPath"/app.json test-e2e/sync/data/actual-app.json |
|||
|
|||
# compare new app.json with expected_app.json |
|||
./node_modules/.bin/jest test-e2e/sync/sync-accounts.js |
@ -0,0 +1,53 @@ |
|||
const pick = require('lodash/pick') |
|||
|
|||
const ACCOUNTS_FIELDS = [ |
|||
'archived', |
|||
'freshAddress', |
|||
'freshAddressPath', |
|||
'id', |
|||
'index', |
|||
'isSegwit', |
|||
'name', |
|||
'path', |
|||
'xpub', |
|||
'operations', |
|||
'currencyId', |
|||
'unitMagnitude', |
|||
'balance', |
|||
] |
|||
|
|||
const OPS_FIELDS = ['id', 'hash', 'accountId', 'type', 'senders', 'recipients', 'value', 'fee'] |
|||
|
|||
const ALPHA_SORT = (a, b) => { |
|||
const aHash = getOpHash(a) |
|||
const bHash = getOpHash(b) |
|||
if (aHash < bHash) return -1 |
|||
if (aHash > bHash) return 1 |
|||
return 0 |
|||
} |
|||
|
|||
describe('sync accounts', () => { |
|||
test('should give the same app.json', () => { |
|||
const expected = getSanitized('./data/expected-app.json') |
|||
const actual = getSanitized('./data/actual-app.json') |
|||
expect(actual).toEqual(expected) |
|||
}) |
|||
}) |
|||
|
|||
function getSanitized(filePath) { |
|||
const data = require(`${filePath}`) // eslint-disable-line import/no-dynamic-require
|
|||
return data.data.accounts |
|||
.map(a => a.data) |
|||
.map(a => pick(a, ACCOUNTS_FIELDS)) |
|||
.map(a => { |
|||
a.operations.sort(ALPHA_SORT) |
|||
return { |
|||
...a, |
|||
operations: a.operations.map(o => pick(o, OPS_FIELDS)), |
|||
} |
|||
}) |
|||
} |
|||
|
|||
function getOpHash(op) { |
|||
return `${op.accountId}--${op.hash}--${op.type}` |
|||
} |
@ -0,0 +1,48 @@ |
|||
/* eslint-disable no-console */ |
|||
|
|||
const electron = require('electron') |
|||
const fs = require('fs') |
|||
const path = require('path') |
|||
const moment = require('moment') |
|||
|
|||
const delay = ms => new Promise(f => setTimeout(f, ms)) |
|||
|
|||
const MIN_TIME_DIFF = 1 * 1000 * 90 // 1.5 minute
|
|||
const PING_INTERVAL = 1 * 1000 // 1 seconds
|
|||
|
|||
async function waitForSync() { |
|||
let MAX_RETRIES = 100 |
|||
const userDataDirectory = electron.app.getPath('userData') |
|||
const tmpAppJSONPath = path.resolve(userDataDirectory, 'app.json') |
|||
const appJSONPath = tmpAppJSONPath.replace('/Electron/', '/Ledger Live/') |
|||
|
|||
function check() { |
|||
const appJSONContent = fs.readFileSync(appJSONPath, 'utf-8') |
|||
const appJSONParsed = JSON.parse(appJSONContent) |
|||
const mapped = appJSONParsed.data.accounts.map(a => ({ |
|||
name: a.data.name, |
|||
lastSyncDate: a.data.lastSyncDate, |
|||
})) |
|||
const now = Date.now() |
|||
const areAllSync = mapped.every(account => { |
|||
const diff = now - new Date(account.lastSyncDate).getTime() |
|||
if (diff <= MIN_TIME_DIFF) return true |
|||
console.log(`[${account.name}] synced ${moment(account.lastSyncDate).fromNow()} (${moment(account.lastSyncDate).format('YYYY-MM-DD HH:mm:ss')})`) |
|||
return false |
|||
}) |
|||
return areAllSync |
|||
} |
|||
|
|||
while (!check()) { |
|||
MAX_RETRIES-- |
|||
if (!MAX_RETRIES) { |
|||
console.log(`x Too much retries. Exitting.`) |
|||
process.exit(1) |
|||
} |
|||
await delay(PING_INTERVAL) |
|||
} |
|||
|
|||
process.exit(0) |
|||
} |
|||
|
|||
waitForSync() |
Loading…
Reference in new issue