diff --git a/README.md b/README.md index 4e2f7ec..c82e7a4 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,56 @@ Ledger Blue is not maintained anymore, but the app can still be compiled for thi This app follows the specification available in the `doc/` folder -To compile it and load it on a device, have a look here: https://ledger.readthedocs.io/en/latest/userspace/getting_started.html \ No newline at end of file +To compile it and load it on a device, have a look here: https://ledger.readthedocs.io/en/latest/userspace/getting_started.html + +# Testing + +Testing is done via the open-source framework [zemu](https://github.com/Zondax/zemu). + +## Running tests + +First [install yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable). +Then you can install the project by simply running: +``` +make test +``` +This will run `make install_tests` and `make run_tests` + +To run a specific tests (here the send test): +``` +cd tests +sudo jest --runInBand --detectOpenHandles src/send.test.js +``` + +Make sure you're in the `tests` folder before running `jest` or `yarn test`. + + +## Adding tests + +### Zemu + +To add tests, copy one of the already existing test files in `tests/src/`. +You then need to adapt the `buffer` and `tx` variables to adapt to the APDU you wish to send. + +- Adapt the expected screen flow. Please create a folder under `tests/snapshots` with the name of the test you're performing. +- Then adapt the `ORIGINAL_SNAPSHOT_PATH_PREFIX` with the name of the folder you just created. +- To create the snapshots, modify the `SNAPSHOT_PATH_PREFIX` and set it to be equal to `ORIGINAL_SNAPSHOT_PATH_PREFIX`. +- Run the tests once, this will create all the snapshots in the folder you created. +- Put back your `SNAPSHOT_PATH_PREFIX` to `snapshots/tmp/`. + +Finally make sure you adapt the expected signature! + +### Update binaries + +Don't forget to update the binaries in the test folder. To do so, compile with those environement variables: +``` +make DEBUG=1 ALLOW_DATA=1 +``` + +Then copy the binary to the `tests/elfs` folder (in this case, compiled with SDK for nanoS): +``` +cp bin/app.elf tests/elfs/ethereum_nanos.elf +``` + +Repeat the operation for a binary compiled with nanoX SDK and change for `ethereum_nanox.elf`. + diff --git a/tests/snapshots/deposit/nanos/accept.png b/tests/snapshots/deposit/nanos/accept.png new file mode 100644 index 0000000..3158ea6 Binary files /dev/null and b/tests/snapshots/deposit/nanos/accept.png differ diff --git a/tests/snapshots/deposit/nanos/address_1.png b/tests/snapshots/deposit/nanos/address_1.png new file mode 100644 index 0000000..49ba7bc Binary files /dev/null and b/tests/snapshots/deposit/nanos/address_1.png differ diff --git a/tests/snapshots/deposit/nanos/address_2.png b/tests/snapshots/deposit/nanos/address_2.png new file mode 100644 index 0000000..4513833 Binary files /dev/null and b/tests/snapshots/deposit/nanos/address_2.png differ diff --git a/tests/snapshots/deposit/nanos/address_3.png b/tests/snapshots/deposit/nanos/address_3.png new file mode 100644 index 0000000..1707a8e Binary files /dev/null and b/tests/snapshots/deposit/nanos/address_3.png differ diff --git a/tests/snapshots/deposit/nanos/amount.png b/tests/snapshots/deposit/nanos/amount.png new file mode 100644 index 0000000..37538c7 Binary files /dev/null and b/tests/snapshots/deposit/nanos/amount.png differ diff --git a/tests/snapshots/deposit/nanos/data_present.png b/tests/snapshots/deposit/nanos/data_present.png new file mode 100644 index 0000000..3bb21d5 Binary files /dev/null and b/tests/snapshots/deposit/nanos/data_present.png differ diff --git a/tests/snapshots/deposit/nanos/fees.png b/tests/snapshots/deposit/nanos/fees.png new file mode 100644 index 0000000..eafd4a2 Binary files /dev/null and b/tests/snapshots/deposit/nanos/fees.png differ diff --git a/tests/snapshots/deposit/nanos/review.png b/tests/snapshots/deposit/nanos/review.png new file mode 100644 index 0000000..2994983 Binary files /dev/null and b/tests/snapshots/deposit/nanos/review.png differ diff --git a/tests/snapshots/deposit/nanox/accept.png b/tests/snapshots/deposit/nanox/accept.png new file mode 100644 index 0000000..7f2b8c8 Binary files /dev/null and b/tests/snapshots/deposit/nanox/accept.png differ diff --git a/tests/snapshots/deposit/nanox/address.png b/tests/snapshots/deposit/nanox/address.png new file mode 100644 index 0000000..0c893f3 Binary files /dev/null and b/tests/snapshots/deposit/nanox/address.png differ diff --git a/tests/snapshots/deposit/nanox/amount.png b/tests/snapshots/deposit/nanox/amount.png new file mode 100644 index 0000000..1523569 Binary files /dev/null and b/tests/snapshots/deposit/nanox/amount.png differ diff --git a/tests/snapshots/deposit/nanox/data_present.png b/tests/snapshots/deposit/nanox/data_present.png new file mode 100644 index 0000000..8af206f Binary files /dev/null and b/tests/snapshots/deposit/nanox/data_present.png differ diff --git a/tests/snapshots/deposit/nanox/fees.png b/tests/snapshots/deposit/nanox/fees.png new file mode 100644 index 0000000..559c155 Binary files /dev/null and b/tests/snapshots/deposit/nanox/fees.png differ diff --git a/tests/snapshots/deposit/nanox/review.png b/tests/snapshots/deposit/nanox/review.png new file mode 100644 index 0000000..8794afe Binary files /dev/null and b/tests/snapshots/deposit/nanox/review.png differ diff --git a/tests/src/approve.test.js b/tests/src/approve.test.js index 0d804f8..579d252 100644 --- a/tests/src/approve.test.js +++ b/tests/src/approve.test.js @@ -6,7 +6,7 @@ import Zemu from "@zondax/zemu"; import { TransportStatusError } from "@ledgerhq/errors"; import { expect } from "../jest"; -const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox} = require("generic.js"); +const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT} = require("generic.js"); const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/approve/"; const SNAPSHOT_PATH_PREFIX = "snapshots/tmp/"; @@ -19,7 +19,7 @@ const SNAPSHOT_PATH_NANOX = SNAPSHOT_PATH_PREFIX + "nanox/"; test("Approve DAI tokens nanos", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOS_ELF_PATH); try { @@ -105,7 +105,7 @@ test("Approve DAI tokens nanos", async () => { }); test("Approve DAI token nanox", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOX_ELF_PATH); try { diff --git a/tests/src/deposit.test.js b/tests/src/deposit.test.js index 139bd0d..b024692 100644 --- a/tests/src/deposit.test.js +++ b/tests/src/deposit.test.js @@ -6,7 +6,7 @@ import Zemu from "@zondax/zemu"; import { TransportStatusError } from "@ledgerhq/errors"; import { expect } from "../jest"; -const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox} = require("generic.js"); +const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT} = require("generic.js"); // Adapt this prefix. const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/deposit/"; @@ -20,7 +20,7 @@ const SNAPSHOT_PATH_NANOX = SNAPSHOT_PATH_PREFIX + "nanox/"; test("Deposit ETH nanos", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOS_ELF_PATH); try { @@ -28,10 +28,12 @@ test("Deposit ETH nanos", async () => { let transport = await sim.getTransport(); - let buffer = Buffer.from("058000002C8000003C800000010000000000000000F8914585055AE826008306599594CC9A0B7C43DC2A5F023BB9B738E45B0EF6B06E0487B1A2BC2EC50000B864474CF53D0000000000000000000000007D2768DE32B0B80B7A3454C06BDAC94A69DDC7A900000000000000000000000070BC641723FAD48BE2DF6CF63DC6270EE2F897430000000000000000000000000000000000", "hex"); - - // Send transaction + let buffer = Buffer.from("058000002c8000003c800000010000000000000000f8924685028fa6ae008306599594cc9a0b7c43dc2a5f023bb9b738e45b0ef6b06e0488016345785d8a0000b864474cf53d0000000000000000000000007d2768de32b0b80b7a3454c06bdac94a69ddc7a900000000000000000000000070bc641723fad48be2df6cf63dc6270ee2f8974300000000000000000000000000000000", "hex"); let tx = transport.send(0xe0, 0x04, 0x00, 0x00, buffer); + + buffer = Buffer.from("00000000000000000000000000000000018080", "hex"); + tx = transport.send(0xe0, 0x04, 0x80, 0x00, buffer); + let filename; await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()); @@ -94,7 +96,7 @@ test("Deposit ETH nanos", async () => { await sim.clickBoth(); await expect(tx).resolves.toEqual( - Buffer.from([ 38, 111, 56, 157, 21, 50, 15, 5, 1, 56, 53, 38, 237, 3, 222, 145, 124, 20, 33, 39, 22, 240, 154, 38, 45, 188, 152, 67, 16, 134, 165, 219, 73, 13, 201, 148, 183, 185, 114, 48, 187, 53, 253, 246, 254, 194, 244, 216, 255, 76, 251, 139, 254, 178, 166, 82, 195, 100, 199, 56, 255, 3, 60, 5, 221, 144, 0]) + Buffer.from([38, 181, 174, 58, 1, 30, 181, 14, 125, 31, 233, 245, 230, 246, 217, 28, 169, 244, 223, 202, 95, 115, 128, 95, 196, 134, 109, 73, 231, 46, 173, 47, 92, 60, 110, 85, 219, 89, 37, 88, 107, 181, 142, 67, 75, 88, 178, 192, 71, 86, 246, 98, 19, 21, 151, 249, 140, 26, 162, 65, 139, 22, 153, 43, 129, 144, 0]) ); } finally { await sim.close(); @@ -102,17 +104,20 @@ test("Deposit ETH nanos", async () => { }); test("Deposit ETH nanox", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOX_ELF_PATH); try { await sim.start(sim_options_nanox); let transport = await sim.getTransport(); - let buffer = Buffer.from("058000002C8000003C800000010000000000000000F8914585055AE826008306599594CC9A0B7C43DC2A5F023BB9B738E45B0EF6B06E0487B1A2BC2EC50000B864474CF53D0000000000000000000000007D2768DE32B0B80B7A3454C06BDAC94A69DDC7A900000000000000000000000070BC641723FAD48BE2DF6CF63DC6270EE2F897430000000000000000000000000000000000", "hex"); - // Send transaction + let buffer = Buffer.from("058000002c8000003c800000010000000000000000f8924685028fa6ae008306599594cc9a0b7c43dc2a5f023bb9b738e45b0ef6b06e0488016345785d8a0000b864474cf53d0000000000000000000000007d2768de32b0b80b7a3454c06bdac94a69ddc7a900000000000000000000000070bc641723fad48be2df6cf63dc6270ee2f8974300000000000000000000000000000000", "hex"); let tx = transport.send(0xe0, 0x04, 0x00, 0x00, buffer); + + buffer = Buffer.from("00000000000000000000000000000000018080", "hex"); + tx = transport.send(0xe0, 0x04, 0x80, 0x00, buffer); + let filename; await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()); @@ -125,9 +130,9 @@ test("Deposit ETH nanox", async () => { // Data present filename = "data_present.png"; - await sim.clickRight(SNAPSHOT_PATH_NANOS + filename); - const data_present = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename); - const expected_data_present = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename); + await sim.clickRight(SNAPSHOT_PATH_NANOX + filename); + const data_present = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename); + const expected_data_present = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename); expect(data_present).toEqual(expected_data_present); // Amount @@ -161,7 +166,7 @@ test("Deposit ETH nanox", async () => { await sim.clickBoth(); await expect(tx).resolves.toEqual( - Buffer.from([ 38, 111, 56, 157, 21, 50, 15, 5, 1, 56, 53, 38, 237, 3, 222, 145, 124, 20, 33, 39, 22, 240, 154, 38, 45, 188, 152, 67, 16, 134, 165, 219, 73, 13, 201, 148, 183, 185, 114, 48, 187, 53, 253, 246, 254, 194, 244, 216, 255, 76, 251, 139, 254, 178, 166, 82, 195, 100, 199, 56, 255, 3, 60, 5, 221, 144, 0]) + Buffer.from([38, 181, 174, 58, 1, 30, 181, 14, 125, 31, 233, 245, 230, 246, 217, 28, 169, 244, 223, 202, 95, 115, 128, 95, 196, 134, 109, 73, 231, 46, 173, 47, 92, 60, 110, 85, 219, 89, 37, 88, 107, 181, 142, 67, 75, 88, 178, 192, 71, 86, 246, 98, 19, 21, 151, 249, 140, 26, 162, 65, 139, 22, 153, 43, 129, 144, 0]) ); } finally { await sim.close(); diff --git a/tests/src/generic.js b/tests/src/generic.js index 0fb103d..59968b4 100644 --- a/tests/src/generic.js +++ b/tests/src/generic.js @@ -18,9 +18,12 @@ const Resolve = require("path").resolve; const NANOS_ELF_PATH = Resolve("elfs/ethereum_nanos.elf"); const NANOX_ELF_PATH = Resolve("elfs/ethereum_nanox.elf"); +const TIMEOUT = 1000000; + module.exports = { NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, - sim_options_nanox + sim_options_nanox, + TIMEOUT, } \ No newline at end of file diff --git a/tests/src/send.test.js b/tests/src/send.test.js index 80bca1e..37cbdee 100644 --- a/tests/src/send.test.js +++ b/tests/src/send.test.js @@ -6,7 +6,7 @@ import Zemu from "@zondax/zemu"; import { TransportStatusError } from "@ledgerhq/errors"; import { expect } from "../jest"; -const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox} = require("generic.js"); +const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT} = require("generic.js"); const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/send/"; const SNAPSHOT_PATH_PREFIX = "snapshots/tmp/"; @@ -17,9 +17,8 @@ const ORIGINAL_SNAPSHOT_PATH_NANOX = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanox/"; const SNAPSHOT_PATH_NANOS = SNAPSHOT_PATH_PREFIX + "nanos/"; const SNAPSHOT_PATH_NANOX = SNAPSHOT_PATH_PREFIX + "nanox/"; - test("Transfer nanos", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOS_ELF_PATH); try { @@ -108,7 +107,7 @@ test("Transfer nanos", async () => { }); test("Transfer nanox", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOX_ELF_PATH); try { diff --git a/tests/src/send_bsc.test.js b/tests/src/send_bsc.test.js index e0a8700..dda50a3 100644 --- a/tests/src/send_bsc.test.js +++ b/tests/src/send_bsc.test.js @@ -6,7 +6,7 @@ import Zemu from "@zondax/zemu"; import { TransportStatusError } from "@ledgerhq/errors"; import { expect } from "../jest"; -const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox} = require("generic.js"); +const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT} = require("generic.js"); const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/send_bsc/"; const SNAPSHOT_PATH_PREFIX = "snapshots/tmp/"; @@ -19,7 +19,7 @@ const SNAPSHOT_PATH_NANOX = SNAPSHOT_PATH_PREFIX + "nanox/"; test("Transfer bsc nanos", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOS_ELF_PATH); try { @@ -116,7 +116,7 @@ test("Transfer bsc nanos", async () => { }); test("Transfer bsc nanox", async () => { - jest.setTimeout(100000); + jest.setTimeout(TIMEOUT); const sim = new Zemu(NANOX_ELF_PATH); try {