From 4834b17d6c151cbd9f4500a69aa6f0d958dfe3a5 Mon Sep 17 00:00:00 2001 From: Oscar Pepper Date: Thu, 9 Nov 2023 16:00:34 +0000 Subject: [PATCH 01/10] laying groundwork for regtest e2e tests --- e2e/loadRecipientWallet.js | 40 +++++++++++++++++++++++++ e2e/reload_while_tx_unconfirmed.test.js | 39 ++++++++++++++++++++++++ rust/android/tests/e2e_tests.rs | 34 +++++++++++++++++++++ rust/android/tests/integration_tests.rs | 39 ++++++++++++++---------- rust/zingomobile_utils/src/lib.rs | 21 +++++++++++++ 5 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 e2e/loadRecipientWallet.js create mode 100644 e2e/reload_while_tx_unconfirmed.test.js create mode 100644 rust/android/tests/e2e_tests.rs diff --git a/e2e/loadRecipientWallet.js b/e2e/loadRecipientWallet.js new file mode 100644 index 000000000..e5d4eabca --- /dev/null +++ b/e2e/loadRecipientWallet.js @@ -0,0 +1,40 @@ +let loadRecipientWallet = async () => { + // the start always is like a fress install -> create a new wallet + // go to setting modal screen + await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('header.drawmenu')).tap(); + await waitFor(element(by.id('menu.settings'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('menu.settings')).tap(); + + // first we need to change the App to advanced mode + await waitFor(element(by.id('settings.mode-advanced'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('settings.mode-advanced')).tap(); + await waitFor(element(by.id('settings.button.save'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('settings.button.save')).tap(); + + // change to another wallet -> restore from seed + await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('header.drawmenu')).tap(); + await waitFor(element(by.id('menu.changewallet'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('menu.changewallet')).tap(); + + await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); + + // three taps to be really sure... + await element(by.id('seed.button.OK')).tap(); + await element(by.id('seed.button.OK')).tap(); + await element(by.id('seed.button.OK')).tap(); + + await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id("loadingapp.restorewalletseed")).tap(); + await waitFor(element(by.id('seed.seedinput'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id("seed.seedinput")).replaceText( + 'hospital museum valve antique skate museum unfold vocal weird milk scale social vessel identify crowd hospital control album rib bulb path oven civil tank' + ); + await waitFor(element(by.id('seed.birthdayinput'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id("seed.birthdayinput")).replaceText('3'); + await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('seed.button.OK')).tap(); +} + +export { loadRecipientWallet }; \ No newline at end of file diff --git a/e2e/reload_while_tx_unconfirmed.test.js b/e2e/reload_while_tx_unconfirmed.test.js new file mode 100644 index 000000000..151a2f857 --- /dev/null +++ b/e2e/reload_while_tx_unconfirmed.test.js @@ -0,0 +1,39 @@ +const { log, device, by, element } = require('detox'); + +import { loadTestWallet } from "./loadTestWallet.js"; + +describe('Renders wallet data correctly.', () => { + // i just pulled this seed out of thin air + it('loads a wallet', loadTestWallet); + + it('correctly renders the scanner', async () => { + await element(by.text('SEND')).tap(); + + await element(by.id('send.scan-button')).tap(); + await expect(element(by.id('scan.cancel'))).toBeVisible(); + await element(by.id('scan.cancel')).tap(); + }); + + it('adds return address to the memo if that option is selected, and correctly renders confirm screen', async () => { + + await element(by.id('send.addressplaceholder')).replaceText( + 'u1lx7nlnqqqs7p4hcqz4hyjgnw7h8zskcgr2f8dfhm96np0gnfdzu7jtms7q2pxd7ufy96wxzdsdy65jvp3td7fj2ltcz0jpak86ddyszl9ykn5s86q3xataya5867z3tj2x8cw0ljyrenymr2gcqmjf50gmexqj233yn3kdaxn2yukwcx87emurufakf82wapgnu5h3fvae6aw9uus2r', + ); + await element(by.id('send.amount')).replaceText('0'); + await element(by.id('send.checkboxUA')).tap(); + await element(by.id('send.scrollView')).scrollTo('bottom'); + await element(by.id('send.memo-field')).replaceText("1\n2\n3\n4\n5\n6\n7\n8"); + await element(by.id('send.scrollView')).scrollTo('bottom'); + await element(by.id('send.button')).tap(); + + await element(by.id('send.confirm.scrollView')).scrollTo('bottom'); + + const memo = element(by.id('send.confirm-memo')); + + await expect(memo).toBeVisible(100); + await expect(memo).toHaveText( + '1\n2\n3\n4\n5\n6\n7\n8\nReply to: \nu1lx7nlnqqqs7p4hcqz4hyjgnw7h8zskcgr2f8dfhm96np0gnfdzu7jtms7q2pxd7ufy96wxzdsdy65jvp3td7fj2ltcz0jpak86ddyszl9ykn5s86q3xataya5867z3tj2x8cw0ljyrenymr2gcqmjf50gmexqj233yn3kdaxn2yukwcx87emurufakf82wapgnu5h3fvae6aw9uus2r', + ); + }); + +}); diff --git a/rust/android/tests/e2e_tests.rs b/rust/android/tests/e2e_tests.rs new file mode 100644 index 000000000..be264003f --- /dev/null +++ b/rust/android/tests/e2e_tests.rs @@ -0,0 +1,34 @@ +#[cfg(not(feature = "regchest"))] +use zingo_testutils::{self, scenarios}; + +#[cfg(feature = "ci")] +const UNIX_SOCKET: Option<&str> = Some("/Users/runner/.colima/default/docker.sock"); +#[cfg(all(not(feature = "ci"), feature = "regchest"))] +const UNIX_SOCKET: Option<&str> = None; + +async fn e2e_reload_while_tx_unconfirmed() { + #[cfg(not(feature = "regchest"))] + let (_regtest_manager, _child_process_handler) = + scenarios::funded_orchard_mobileclient(1_000_000).await; + #[cfg(feature = "regchest")] + let docker = + match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_mobileclient")).await { + Ok(d) => d, + Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), + }; + + let (exit_code, output, error) = + zingomobile_utils::android_e2e_test("reload_while_tx_unconfirmed"); + + #[cfg(feature = "regchest")] + match regchest_utils::close(&docker).await { + Ok(_) => (), + Err(e) => panic!("Failed to close regchest docker container: {:?}", e), + } + + println!("Exit Code: {}", exit_code); + println!("Output: {}", output); + println!("Error: {}", error); + + assert_eq!(exit_code, 0); +} diff --git a/rust/android/tests/integration_tests.rs b/rust/android/tests/integration_tests.rs index a08d8a6f6..013e82f29 100644 --- a/rust/android/tests/integration_tests.rs +++ b/rust/android/tests/integration_tests.rs @@ -1,4 +1,3 @@ -#![forbid(unsafe_code)] #[cfg(not(feature = "regchest"))] use zingo_testutils::{self, scenarios}; @@ -20,13 +19,14 @@ async fn offline_testsuite(abi: &str) { async fn execute_sync_from_seed(abi: &str) { #[cfg(not(feature = "regchest"))] - let (_regtest_manager, _child_process_handler) = + let (_regtest_manager, _child_process_handler) = scenarios::funded_orchard_mobileclient(1_000_000).await; #[cfg(feature = "regchest")] - let docker = match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_mobileclient")).await { - Ok(d) => d, - Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), - }; + let docker = + match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_mobileclient")).await { + Ok(d) => d, + Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), + }; let (exit_code, output, error) = zingomobile_utils::android_integration_test(abi, "ExecuteSyncFromSeed"); @@ -49,10 +49,11 @@ async fn execute_send_from_orchard(abi: &str) { let (_regtest_manager, _child_process_handler) = scenarios::funded_orchard_mobileclient(1_000_000).await; #[cfg(feature = "regchest")] - let docker = match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_mobileclient")).await { - Ok(d) => d, - Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), - }; + let docker = + match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_mobileclient")).await { + Ok(d) => d, + Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), + }; let (exit_code, output, error) = zingomobile_utils::android_integration_test(abi, "ExecuteSendFromOrchard"); @@ -75,10 +76,13 @@ async fn execute_currentprice_and_summaries_from_seed(abi: &str) { let (_regtest_manager, _child_process_handler) = scenarios::funded_orchard_with_3_txs_mobileclient(1_000_000).await; #[cfg(feature = "regchest")] - let docker = match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_with_3_txs_mobileclient")).await { - Ok(d) => d, - Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), - }; + let docker = + match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_with_3_txs_mobileclient")) + .await + { + Ok(d) => d, + Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), + }; let (exit_code, output, error) = zingomobile_utils::android_integration_test(abi, "UpdateCurrentPriceAndSummariesFromSeed"); @@ -101,7 +105,12 @@ async fn execute_sapling_balance_from_seed(abi: &str) { let (_regtest_manager, _child_process_handler) = scenarios::funded_orchard_sapling_transparent_shielded_mobileclient(1_000_000).await; #[cfg(feature = "regchest")] - let docker = match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_sapling_transparent_shielded_mobileclient")).await { + let docker = match regchest_utils::launch( + UNIX_SOCKET, + Some("funded_orchard_sapling_transparent_shielded_mobileclient"), + ) + .await + { Ok(d) => d, Err(e) => panic!("Failed to launch regchest docker container: {:?}", e), }; diff --git a/rust/zingomobile_utils/src/lib.rs b/rust/zingomobile_utils/src/lib.rs index 0c6c09445..613575130 100644 --- a/rust/zingomobile_utils/src/lib.rs +++ b/rust/zingomobile_utils/src/lib.rs @@ -33,3 +33,24 @@ pub fn android_integration_test(abi: &str, test_name: &str) -> (i32, String, Str (exit_code, stdout, stderr) } + +pub fn android_e2e_test(test_name: &str) -> (i32, String, String) { + let output = Command::new("sh") + .arg("-c") + .arg(format!( + r#" + cd $(git rev-parse --show-toplevel) + yarn detox build -c android.att.debug + yarn detox test -c android.att.debug {} + "#, + test_name + )) + .output() + .expect("Failed to execute command"); + + let exit_code = output.status.code().unwrap_or(-1); + let stdout = String::from_utf8_lossy(&output.stdout).to_string(); + let stderr = String::from_utf8_lossy(&output.stderr).to_string(); + + (exit_code, stdout, stderr) +} From 7ef476b78fd44d127e91169bbb4406b168442f0a Mon Sep 17 00:00:00 2001 From: Oscar Pepper Date: Thu, 9 Nov 2023 16:28:16 +0000 Subject: [PATCH 02/10] add click confirm to change wallet successfully --- e2e/loadRecipientWallet.js | 4 ---- e2e/loadTestWallet.js | 6 ++---- rust/android/tests/e2e_tests.rs | 2 +- rust/zingomobile_utils/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/e2e/loadRecipientWallet.js b/e2e/loadRecipientWallet.js index e5d4eabca..6c3b1f234 100644 --- a/e2e/loadRecipientWallet.js +++ b/e2e/loadRecipientWallet.js @@ -19,10 +19,6 @@ let loadRecipientWallet = async () => { await element(by.id('menu.changewallet')).tap(); await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); - - // three taps to be really sure... - await element(by.id('seed.button.OK')).tap(); - await element(by.id('seed.button.OK')).tap(); await element(by.id('seed.button.OK')).tap(); await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); diff --git a/e2e/loadTestWallet.js b/e2e/loadTestWallet.js index 78608a1e3..09a261d56 100644 --- a/e2e/loadTestWallet.js +++ b/e2e/loadTestWallet.js @@ -20,10 +20,6 @@ let loadTestWallet = async () => { await element(by.id('menu.changewallet')).tap(); await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); - - // three taps to be really sure... - await element(by.id('seed.button.OK')).tap(); - await element(by.id('seed.button.OK')).tap(); await element(by.id('seed.button.OK')).tap(); await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); @@ -36,6 +32,8 @@ let loadTestWallet = async () => { await element(by.id("seed.birthdayinput")).replaceText('1994579'); await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('seed.button.OK')).tap(); + await waitFor(element(by.text('CONFIRM'))).toBeVisible().withTimeout(sync_timeout); + await element(by.text('CONFIRM')).tap(); } export { loadTestWallet }; \ No newline at end of file diff --git a/rust/android/tests/e2e_tests.rs b/rust/android/tests/e2e_tests.rs index be264003f..777ac785e 100644 --- a/rust/android/tests/e2e_tests.rs +++ b/rust/android/tests/e2e_tests.rs @@ -18,7 +18,7 @@ async fn e2e_reload_while_tx_unconfirmed() { }; let (exit_code, output, error) = - zingomobile_utils::android_e2e_test("reload_while_tx_unconfirmed"); + zingomobile_utils::android_e2e_test("reload_while_tx_unconfirmed.test.js"); #[cfg(feature = "regchest")] match regchest_utils::close(&docker).await { diff --git a/rust/zingomobile_utils/src/lib.rs b/rust/zingomobile_utils/src/lib.rs index 613575130..e4d9eb300 100644 --- a/rust/zingomobile_utils/src/lib.rs +++ b/rust/zingomobile_utils/src/lib.rs @@ -41,7 +41,7 @@ pub fn android_e2e_test(test_name: &str) -> (i32, String, String) { r#" cd $(git rev-parse --show-toplevel) yarn detox build -c android.att.debug - yarn detox test -c android.att.debug {} + yarn detox test -c android.att.debug {}.test.js "#, test_name )) From c5a608ae8c65ebb23e1641ebcb209f4676e1dbcd Mon Sep 17 00:00:00 2001 From: Oscar Pepper Date: Thu, 9 Nov 2023 18:17:10 +0000 Subject: [PATCH 03/10] starting to try connecting to regtest network --- app/LoadingApp/LoadingApp.tsx | 1 + e2e/loadRecipientWallet.js | 11 +++++-- e2e/loadTestWallet.js | 5 ++- e2e/reload_while_tx_unconfirmed.test.js | 41 ++++++------------------- 4 files changed, 22 insertions(+), 36 deletions(-) diff --git a/app/LoadingApp/LoadingApp.tsx b/app/LoadingApp/LoadingApp.tsx index 0d9479a41..9ba030d66 100644 --- a/app/LoadingApp/LoadingApp.tsx +++ b/app/LoadingApp/LoadingApp.tsx @@ -684,6 +684,7 @@ export class LoadingAppClass extends Component {mode === 'basic' ? ( } buttonStyle={{ width: 48, padding: 10, resizeMode: 'contain' }} destructiveIndex={5} diff --git a/e2e/loadRecipientWallet.js b/e2e/loadRecipientWallet.js index 6c3b1f234..4917d1796 100644 --- a/e2e/loadRecipientWallet.js +++ b/e2e/loadRecipientWallet.js @@ -1,3 +1,4 @@ +// loads the 'recipient' from zingolib mobileclient regtest scenarios let loadRecipientWallet = async () => { // the start always is like a fress install -> create a new wallet // go to setting modal screen @@ -12,15 +13,21 @@ let loadRecipientWallet = async () => { await waitFor(element(by.id('settings.button.save'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('settings.button.save')).tap(); - // change to another wallet -> restore from seed + // change to another wallet await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('header.drawmenu')).tap(); await waitFor(element(by.id('menu.changewallet'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('menu.changewallet')).tap(); - await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('seed.button.OK')).tap(); + await waitFor(element(by.text('CONFIRM'))).toBeVisible().withTimeout(sync_timeout); + await element(by.text('CONFIRM')).tap(); + + // connect to regtest network + await waitFor(element(by.id('options.menu'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('options.menu')).tap(); + // restore from seed await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); await element(by.id("loadingapp.restorewalletseed")).tap(); await waitFor(element(by.id('seed.seedinput'))).toBeVisible().withTimeout(sync_timeout); diff --git a/e2e/loadTestWallet.js b/e2e/loadTestWallet.js index 09a261d56..a6f4489f1 100644 --- a/e2e/loadTestWallet.js +++ b/e2e/loadTestWallet.js @@ -18,9 +18,10 @@ let loadTestWallet = async () => { await element(by.id('header.drawmenu')).tap(); await waitFor(element(by.id('menu.changewallet'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('menu.changewallet')).tap(); - await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('seed.button.OK')).tap(); + await waitFor(element(by.text('CONFIRM'))).toBeVisible().withTimeout(sync_timeout); + await element(by.text('CONFIRM')).tap(); await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); await element(by.id("loadingapp.restorewalletseed")).tap(); @@ -32,8 +33,6 @@ let loadTestWallet = async () => { await element(by.id("seed.birthdayinput")).replaceText('1994579'); await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('seed.button.OK')).tap(); - await waitFor(element(by.text('CONFIRM'))).toBeVisible().withTimeout(sync_timeout); - await element(by.text('CONFIRM')).tap(); } export { loadTestWallet }; \ No newline at end of file diff --git a/e2e/reload_while_tx_unconfirmed.test.js b/e2e/reload_while_tx_unconfirmed.test.js index 151a2f857..6e2875e0c 100644 --- a/e2e/reload_while_tx_unconfirmed.test.js +++ b/e2e/reload_while_tx_unconfirmed.test.js @@ -1,39 +1,18 @@ const { log, device, by, element } = require('detox'); -import { loadTestWallet } from "./loadTestWallet.js"; +import { loadRecipientWallet } from "./loadRecipientWallet.js"; describe('Renders wallet data correctly.', () => { // i just pulled this seed out of thin air - it('loads a wallet', loadTestWallet); - - it('correctly renders the scanner', async () => { - await element(by.text('SEND')).tap(); - - await element(by.id('send.scan-button')).tap(); - await expect(element(by.id('scan.cancel'))).toBeVisible(); - await element(by.id('scan.cancel')).tap(); - }); - - it('adds return address to the memo if that option is selected, and correctly renders confirm screen', async () => { - - await element(by.id('send.addressplaceholder')).replaceText( - 'u1lx7nlnqqqs7p4hcqz4hyjgnw7h8zskcgr2f8dfhm96np0gnfdzu7jtms7q2pxd7ufy96wxzdsdy65jvp3td7fj2ltcz0jpak86ddyszl9ykn5s86q3xataya5867z3tj2x8cw0ljyrenymr2gcqmjf50gmexqj233yn3kdaxn2yukwcx87emurufakf82wapgnu5h3fvae6aw9uus2r', - ); - await element(by.id('send.amount')).replaceText('0'); - await element(by.id('send.checkboxUA')).tap(); - await element(by.id('send.scrollView')).scrollTo('bottom'); - await element(by.id('send.memo-field')).replaceText("1\n2\n3\n4\n5\n6\n7\n8"); - await element(by.id('send.scrollView')).scrollTo('bottom'); - await element(by.id('send.button')).tap(); + it('loads a wallet', loadRecipientWallet); - await element(by.id('send.confirm.scrollView')).scrollTo('bottom'); - - const memo = element(by.id('send.confirm-memo')); + // it('adds return address to the memo if that option is selected, and correctly renders confirm screen', async () => { + // await element(by.id('send.addressplaceholder')).replaceText( + // 'zregtestsapling1fkc26vpg566hgnx33n5uvgye4neuxt4358k68atnx78l5tg2dewdycesmr4m5pn56ffzsa7lyj6', + // ); + // await element(by.id('send.amount')).replaceText('20000'); + // await element(by.id('send.scrollView')).scrollTo('bottom'); + // await element(by.id('send.button')).tap(); - await expect(memo).toBeVisible(100); - await expect(memo).toHaveText( - '1\n2\n3\n4\n5\n6\n7\n8\nReply to: \nu1lx7nlnqqqs7p4hcqz4hyjgnw7h8zskcgr2f8dfhm96np0gnfdzu7jtms7q2pxd7ufy96wxzdsdy65jvp3td7fj2ltcz0jpak86ddyszl9ykn5s86q3xataya5867z3tj2x8cw0ljyrenymr2gcqmjf50gmexqj233yn3kdaxn2yukwcx87emurufakf82wapgnu5h3fvae6aw9uus2r', - ); - }); - + // }); }); From 0370afad09d342b60f22d8dc4a3e8c05dbf8aaa1 Mon Sep 17 00:00:00 2001 From: Oscar Pepper Date: Thu, 9 Nov 2023 19:26:50 +0000 Subject: [PATCH 04/10] successfully connecting to regtest network --- app/LoadingApp/LoadingApp.tsx | 1 - components/Components/ChainTypeToggle.tsx | 15 +++++++++++--- e2e/loadRecipientWallet.js | 24 +++++++++++++---------- rust/android/tests/e2e_tests.rs | 3 ++- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/app/LoadingApp/LoadingApp.tsx b/app/LoadingApp/LoadingApp.tsx index 9ba030d66..0d9479a41 100644 --- a/app/LoadingApp/LoadingApp.tsx +++ b/app/LoadingApp/LoadingApp.tsx @@ -684,7 +684,6 @@ export class LoadingAppClass extends Component {mode === 'basic' ? ( } buttonStyle={{ width: 48, padding: 10, resizeMode: 'contain' }} destructiveIndex={5} diff --git a/components/Components/ChainTypeToggle.tsx b/components/Components/ChainTypeToggle.tsx index 0c3a65ef7..aa9d8531f 100644 --- a/components/Components/ChainTypeToggle.tsx +++ b/components/Components/ChainTypeToggle.tsx @@ -23,7 +23,10 @@ const ChainTypeToggle: React.FunctionComponent = ({ return ( - onPress('main')}> + onPress('main')}> = ({ - onPress('test')}> + onPress('test')}> = ({ - onPress('regtest')}> + onPress('regtest')}> { // the start always is like a fress install -> create a new wallet - // go to setting modal screen + // first we need to change the App to advanced mode await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('header.drawmenu')).tap(); await waitFor(element(by.id('menu.settings'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('menu.settings')).tap(); - - // first we need to change the App to advanced mode await waitFor(element(by.id('settings.mode-advanced'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('settings.mode-advanced')).tap(); await waitFor(element(by.id('settings.button.save'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('settings.button.save')).tap(); - // change to another wallet + // connect to regtest network + await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('header.drawmenu')).tap(); - await waitFor(element(by.id('menu.changewallet'))).toBeVisible().withTimeout(sync_timeout); - await element(by.id('menu.changewallet')).tap(); + await waitFor(element(by.id('menu.settings'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('menu.settings')).tap(); + + await element(by.id('settings.scrollView')).scroll(700, 'down'); + await waitFor(element(by.id('settings.customServer'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id('settings.customServer')).tap(); + await waitFor(element(by.id('settings.customServerChain.regtest'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id("settings.customServerChain.regtest")).tap(); + await waitFor(element(by.id('settings.customServerField'))).toBeVisible().withTimeout(sync_timeout); + await element(by.id("settings.customServerField")).replaceText('http://10.0.2.2:20000'); + await element(by.id('settings.button.save')).tap(); await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('seed.button.OK')).tap(); await waitFor(element(by.text('CONFIRM'))).toBeVisible().withTimeout(sync_timeout); await element(by.text('CONFIRM')).tap(); - // connect to regtest network - await waitFor(element(by.id('options.menu'))).toBeVisible().withTimeout(sync_timeout); - await element(by.id('options.menu')).tap(); - // restore from seed await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); await element(by.id("loadingapp.restorewalletseed")).tap(); diff --git a/rust/android/tests/e2e_tests.rs b/rust/android/tests/e2e_tests.rs index 777ac785e..fcdda0a44 100644 --- a/rust/android/tests/e2e_tests.rs +++ b/rust/android/tests/e2e_tests.rs @@ -6,6 +6,7 @@ const UNIX_SOCKET: Option<&str> = Some("/Users/runner/.colima/default/docker.soc #[cfg(all(not(feature = "ci"), feature = "regchest"))] const UNIX_SOCKET: Option<&str> = None; +#[tokio::test] async fn e2e_reload_while_tx_unconfirmed() { #[cfg(not(feature = "regchest"))] let (_regtest_manager, _child_process_handler) = @@ -18,7 +19,7 @@ async fn e2e_reload_while_tx_unconfirmed() { }; let (exit_code, output, error) = - zingomobile_utils::android_e2e_test("reload_while_tx_unconfirmed.test.js"); + zingomobile_utils::android_e2e_test("reload_while_tx_unconfirmed"); #[cfg(feature = "regchest")] match regchest_utils::close(&docker).await { From ab0caf8d2b39892b7ec5e97698d15b23b2a5165b Mon Sep 17 00:00:00 2001 From: Oscar Pepper Date: Thu, 9 Nov 2023 19:39:32 +0000 Subject: [PATCH 05/10] cleanup --- e2e/loadRecipientWallet.js | 9 +++++---- rust/android/tests/e2e_tests.rs | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/e2e/loadRecipientWallet.js b/e2e/loadRecipientWallet.js index 9709ad2ea..4516328ec 100644 --- a/e2e/loadRecipientWallet.js +++ b/e2e/loadRecipientWallet.js @@ -1,7 +1,8 @@ // loads the 'recipient' from zingolib mobileclient regtest scenarios +// requires e2e test to be run by cargo test runner +// see `rust/android/test/e2e_tests.rs` let loadRecipientWallet = async () => { - // the start always is like a fress install -> create a new wallet - // first we need to change the App to advanced mode + // switch to advanced mode await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('header.drawmenu')).tap(); await waitFor(element(by.id('menu.settings'))).toBeVisible().withTimeout(sync_timeout); @@ -12,12 +13,10 @@ let loadRecipientWallet = async () => { await element(by.id('settings.button.save')).tap(); // connect to regtest network - await waitFor(element(by.id('header.drawmenu'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('header.drawmenu')).tap(); await waitFor(element(by.id('menu.settings'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('menu.settings')).tap(); - await element(by.id('settings.scrollView')).scroll(700, 'down'); await waitFor(element(by.id('settings.customServer'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('settings.customServer')).tap(); @@ -42,6 +41,8 @@ let loadRecipientWallet = async () => { await element(by.id("seed.birthdayinput")).replaceText('3'); await waitFor(element(by.id('seed.button.OK'))).toBeVisible().withTimeout(sync_timeout); await element(by.id('seed.button.OK')).tap(); + + await waitFor(element(by.id('loadingapp.restorewalletseed'))).toBeVisible().withTimeout(sync_timeout); } export { loadRecipientWallet }; \ No newline at end of file diff --git a/rust/android/tests/e2e_tests.rs b/rust/android/tests/e2e_tests.rs index fcdda0a44..69c6288b4 100644 --- a/rust/android/tests/e2e_tests.rs +++ b/rust/android/tests/e2e_tests.rs @@ -10,7 +10,7 @@ const UNIX_SOCKET: Option<&str> = None; async fn e2e_reload_while_tx_unconfirmed() { #[cfg(not(feature = "regchest"))] let (_regtest_manager, _child_process_handler) = - scenarios::funded_orchard_mobileclient(1_000_000).await; + scenarios::funded_orchard_mobileclient(2_000_000).await; #[cfg(feature = "regchest")] let docker = match regchest_utils::launch(UNIX_SOCKET, Some("funded_orchard_mobileclient")).await { From 61a36e775a26f3038755dc6e548e1666cfddcb21 Mon Sep 17 00:00:00 2001 From: Oscar Pepper Date: Fri, 10 Nov 2023 14:34:34 +0000 Subject: [PATCH 06/10] improved e2e framework and added failing halloween bug test --- .detoxrc.js | 2 +- app/LoadedApp/components/Menu.tsx | 2 +- components/Components/ZecAmount.tsx | 5 ++ components/Pools/Pools.tsx | 7 +- e2e/change_custom_server.test.js | 2 +- e2e/change_custom_testnet_server.test.js | 2 +- e2e/change_server_from_list.test.js | 2 +- e2e/{ => e2e-utils}/jest.config.js | 6 +- e2e/e2e-utils/loadRecipientWallet.js | 31 +++++++++ e2e/{ => e2e-utils}/loadTestWallet.js | 0 e2e/e2e-utils/setup-jest.js | 5 ++ e2e/loadRecipientWallet.js | 48 -------------- e2e/reload_while_tx_unconfirmed.test.js | 82 ++++++++++++++++++++---- e2e/screen_awake.test.js | 2 +- e2e/send.test.js | 2 +- e2e/setup-jest.js | 7 -- e2e/sync_report.test.js | 2 +- e2e/transaction_history.test.js | 2 +- rust/android/tests/e2e_tests.rs | 48 +++++++------- 19 files changed, 155 insertions(+), 102 deletions(-) rename e2e/{ => e2e-utils}/jest.config.js (79%) create mode 100644 e2e/e2e-utils/loadRecipientWallet.js rename e2e/{ => e2e-utils}/loadTestWallet.js (100%) create mode 100644 e2e/e2e-utils/setup-jest.js delete mode 100644 e2e/loadRecipientWallet.js delete mode 100644 e2e/setup-jest.js diff --git a/.detoxrc.js b/.detoxrc.js index 3b0431b09..8dd163ff1 100644 --- a/.detoxrc.js +++ b/.detoxrc.js @@ -3,7 +3,7 @@ module.exports = { testRunner: { args: { '$0': 'jest', - config: 'e2e/jest.config.js', + config: 'e2e/e2e-utils/jest.config.js', "testTimeout": 1000000, }, jest: { diff --git a/app/LoadedApp/components/Menu.tsx b/app/LoadedApp/components/Menu.tsx index 2b2006fc8..fded23b52 100644 --- a/app/LoadedApp/components/Menu.tsx +++ b/app/LoadedApp/components/Menu.tsx @@ -87,7 +87,7 @@ const Menu: React.FunctionComponent = ({ onItemSelected }) => { )} {mode !== 'basic' && ( - onItemSelectedWrapper('Fund Pools')} style={item}> + onItemSelectedWrapper('Fund Pools')} style={item}> {translate('loadedapp.fundpools') as string} )} diff --git a/components/Components/ZecAmount.tsx b/components/Components/ZecAmount.tsx index 3845c2baf..dadb97d0f 100644 --- a/components/Components/ZecAmount.tsx +++ b/components/Components/ZecAmount.tsx @@ -16,6 +16,7 @@ type ZecAmountProps = { currencyName: string; privacy?: boolean; smallPrefix?: boolean; + testID?: string; }; const ZecAmount: React.FunctionComponent = ({ @@ -26,6 +27,7 @@ const ZecAmount: React.FunctionComponent = ({ amtZec, privacy, smallPrefix, + testID, }) => { const [privacyHigh, setPrivacyHigh] = useState(privacy || false); const splits = Utils.splitZecAmountIntoBigSmall(amtZec); @@ -76,6 +78,7 @@ const ZecAmount: React.FunctionComponent = ({ = ({ ) : ( = ({ )} {splits.smallPart !== '0000' && !privacyHigh && ( = ({ closeModal, set_privacy_op = ({ closeModal, set_privacy_op = ({ closeModal, set_privacy_op = ({ closeModal, set_privacy_op = ({ closeModal, set_privacy_op = ({ closeModal, set_privacy_op alignItems: 'center', marginVertical: 5, }}> -