Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
4aadafb
acceptReceivedPayment for onchain payments
piotr-iohk Nov 26, 2025
f126c88
adjust PaymentConfirmedToast
piotr-iohk Nov 26, 2025
a15e8c5
acknowledgeReceivedPayment
piotr-iohk Nov 26, 2025
fddb498
waitForToast
piotr-iohk Nov 27, 2025
1429c64
temp adjust boost_1
piotr-iohk Nov 27, 2025
4d605ce
remove refresh in boost
piotr-iohk Nov 27, 2025
94684a5
remove PaymentConfirmedToast and TransactionConfirmedToast
piotr-iohk Nov 27, 2025
dfaefee
update toast ids
piotr-iohk Nov 27, 2025
1cbd12b
update RBF
piotr-iohk Nov 27, 2025
ba705e0
onchain PaymentConfirmedToast
piotr-iohk Nov 27, 2025
b4fc769
adjust CPFP
piotr-iohk Nov 27, 2025
96ff42c
transfer_1 stability
piotr-iohk Nov 28, 2025
00c5fa0
lightning stability sleep
piotr-iohk Nov 28, 2025
3bfcbf4
lightning adjustments + stability
piotr-iohk Nov 28, 2025
4c4acf8
waitForBackup in lightning
piotr-iohk Nov 28, 2025
38814ae
RGS and Electrum toast ids
piotr-iohk Dec 1, 2025
2f92f3d
adjust settings_10
piotr-iohk Dec 1, 2025
7960b38
Merge pull request #58 from synonymdev/fix/toast-ui
piotr-iohk Dec 2, 2025
2f308ab
add Balance toast ids and dismiss to waitForToast
piotr-iohk Dec 3, 2025
a0c52a9
remove tapBalanceToReset in launchFreshApp
piotr-iohk Dec 3, 2025
e6475a5
add BalanceUnitSwitchedToast
piotr-iohk Dec 3, 2025
d30efb3
disable check for iOS (bitkit-ios/issues/260)
piotr-iohk Dec 3, 2025
2b69f8b
stability
piotr-iohk Dec 3, 2025
187b90e
adjust settings_10 after ios fix
piotr-iohk Dec 3, 2025
71782ae
adjust lightning
piotr-iohk Dec 3, 2025
986e644
Merge pull request #61 from synonymdev/feat/balance-toasts
piotr-iohk Dec 3, 2025
dfb26a6
Merge pull request #62 from synonymdev/fix/electrum-settings
piotr-iohk Dec 3, 2025
a7e940c
Adjust lightning
piotr-iohk Dec 2, 2025
9168cbb
stability
piotr-iohk Dec 3, 2025
562b9d4
acceptReceivedPayment for onchain payments
piotr-iohk Nov 26, 2025
3f8deab
adjust PaymentConfirmedToast
piotr-iohk Nov 26, 2025
388a447
acknowledgeReceivedPayment
piotr-iohk Nov 26, 2025
cae95a9
waitForToast
piotr-iohk Nov 27, 2025
71ea9f7
temp adjust boost_1
piotr-iohk Nov 27, 2025
a14f6e7
remove refresh in boost
piotr-iohk Nov 27, 2025
23b66f8
remove PaymentConfirmedToast and TransactionConfirmedToast
piotr-iohk Nov 27, 2025
a32e017
update toast ids
piotr-iohk Nov 27, 2025
8cb0bb5
update RBF
piotr-iohk Nov 27, 2025
61ff965
onchain PaymentConfirmedToast
piotr-iohk Nov 27, 2025
715373c
adjust CPFP
piotr-iohk Nov 27, 2025
fd994ae
transfer_1 stability
piotr-iohk Nov 28, 2025
1f38b6f
lightning stability sleep
piotr-iohk Nov 28, 2025
bd481f0
lightning adjustments + stability
piotr-iohk Nov 28, 2025
79a2efa
waitForBackup in lightning
piotr-iohk Nov 28, 2025
08a779c
RGS and Electrum toast ids
piotr-iohk Dec 1, 2025
7080f52
adjust settings_10
piotr-iohk Dec 1, 2025
9f5a835
adjust lightning
piotr-iohk Dec 3, 2025
67f502b
add Balance toast ids and dismiss to waitForToast
piotr-iohk Dec 3, 2025
5949f58
remove tapBalanceToReset in launchFreshApp
piotr-iohk Dec 3, 2025
671ed9d
add BalanceUnitSwitchedToast
piotr-iohk Dec 3, 2025
bbe15d5
disable check for iOS (bitkit-ios/issues/260)
piotr-iohk Dec 3, 2025
fabf726
stability
piotr-iohk Dec 3, 2025
7a264aa
adjust settings_10 after ios fix
piotr-iohk Dec 3, 2025
3de440d
Merge branch 'feat/onchain-events' into test/lightning
piotr-iohk Dec 4, 2025
2f5cd13
Merge pull request #60 from synonymdev/test/lightning
piotr-iohk Dec 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 65 additions & 10 deletions test/helpers/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -647,11 +647,10 @@ export async function receiveOnchainFunds(
const address = await getReceiveAddress();
await swipeFullScreen('down');
await rpc.sendToAddress(address, btc);
await mineBlocks(rpc, blocksToMine);

// https://github.com/synonymdev/bitkit-android/issues/268
// send - onchain - receiver sees no confetti — missing-in-ldk-node missing onchain payment event
// await elementById('ReceivedTransaction').waitForDisplayed();
await acknowledgeReceivedPayment();

await mineBlocks(rpc, blocksToMine);

if (driver.isAndroid) {
await dismissBackupTimedSheet();
Expand All @@ -671,6 +670,41 @@ export async function receiveOnchainFunds(
}
}

export type ToastId =
| 'BalanceUnitSwitchedToast'
| 'BalanceHiddenToast'
| 'RgsUpdatedToast'
| 'RgsErrorToast'
| 'ElectrumErrorToast'
| 'ElectrumUpdatedToast'
| 'PaymentFailedToast'
| 'ReceivedTransactionReplacedToast'
| 'TransactionReplacedToast'
| 'TransactionUnconfirmedToast'
| 'TransactionRemovedToast';

export async function waitForToast(
toastId: ToastId,
{ waitToDisappear = false, dismiss = true } = {}
) {
await elementById(toastId).waitForDisplayed();
if (waitToDisappear) {
await elementById(toastId).waitForDisplayed({ reverse: true });
return;
}
if (dismiss) {
await dragOnElement(toastId, 'up', 0.2);
}
}

/** Acknowledges the received payment notification by tapping the button.
*/
export async function acknowledgeReceivedPayment() {
await elementById('ReceivedTransaction').waitForDisplayed();
await tap('ReceivedTransactionButton');
await sleep(300);
}

/**
* Triggers the timed backup sheet by navigating to settings and back.
* Since timed sheets are sometimes triggered by user behavior (when user goes back to home screen),
Expand All @@ -681,12 +715,25 @@ export async function receiveOnchainFunds(
* await doTriggerTimedSheet();
*/
export async function doTriggerTimedSheet() {
await sleep(700); // wait for any previous animations to finish
await tap('HeaderMenu');
await tap('DrawerSettings');
await sleep(500); // wait for the app to settle
await doNavigationClose();
}

export async function dismissBackgroundPaymentsTimedSheet({
triggerTimedSheet = false,
}: { triggerTimedSheet?: boolean } = {}) {
if (triggerTimedSheet) {
await doTriggerTimedSheet();
}
await elementById('BackgroundPaymentsDescription').waitForDisplayed();
await sleep(500); // wait for the app to settle
await tap('BackgroundPaymentsCancel');
await sleep(500);
}

/**
* Dismisses the backup reminder sheet.
* This sheet is triggered by first onchain balance change.
Expand All @@ -710,7 +757,7 @@ export async function dismissBackupTimedSheet({
}
await elementById('BackupIntroViewDescription').waitForDisplayed();
await sleep(500); // wait for the app to settle
await tap('BackupIntroViewCancel');
await swipeFullScreen('down');
await sleep(500);
}

Expand All @@ -732,14 +779,22 @@ export async function dismissBackupTimedSheet({
export async function dismissQuickPayIntro({
triggerTimedSheet = false,
}: { triggerTimedSheet?: boolean } = {}) {
if (driver.isIOS) return; // Not supported on iOS yet
if (triggerTimedSheet) {
await doTriggerTimedSheet();
}
await elementById('QuickpayIntro-button').waitForDisplayed();
await sleep(500); // wait for the app to settle
await swipeFullScreen('down');
await sleep(500);

if (driver.isAndroid) {
// TODO: it's temp, change on Android to match iOS testID
await elementById('QuickpayIntro-button').waitForDisplayed();
await sleep(500); // wait for the app to settle
await swipeFullScreen('down');
await sleep(500);
} else {
await elementById('QuickpayIntroDescription').waitForDisplayed();
await sleep(500); // wait for the app to settle
await tap('QuickpayIntroCancel');
await sleep(500);
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions test/helpers/lnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export async function getLDKNodeID(): Promise<string> {
await elementById('LDKNodeID').waitForDisplayed({ timeout: 60_000 });
const ldkNodeId = (await elementById('LDKNodeID').getText()).trim();
console.info({ ldkNodeId });
await sleep(500);
await tap('NavigationBack');
return ldkNodeId;
}
Expand Down
25 changes: 3 additions & 22 deletions test/helpers/setup.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,13 @@
import { execSync } from 'node:child_process';
import { elementsById, sleep, tap } from './actions';
import { sleep } from './actions';
import { getAppId, getAppPath } from './constants';

export async function launchFreshApp({ tryHandleAlert = true } = {}) {
export async function launchFreshApp() {
const appId = getAppId();

await driver.terminateApp(appId);
await driver.activateApp(appId);
// workaround to get rid of "Bitkit is running in background" alert
if (tryHandleAlert) {
await sleep(1000);
try {
await tapBalanceToReset();
} catch {
await tapBalanceToReset();
}
}
await sleep(500);
}

async function tapBalanceToReset() {
await tap('TotalBalance');
const moneyFiatSymbols = await elementsById('MoneyFiatSymbol');
moneyFiatSymbols[0].waitForDisplayed();
moneyFiatSymbols[1].waitForDisplayed();
if ((await moneyFiatSymbols[1].getText()) !== '₿') {
await tap('TotalBalance');
}
await sleep(3000);
}

/**
Expand Down
94 changes: 27 additions & 67 deletions test/specs/boost.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
elementByIdWithin,
getTextUnder,
mineBlocks,
attemptRefreshOnHomeScreen,
doNavigationClose,
getSeed,
waitForBackup,
Expand Down Expand Up @@ -80,25 +79,16 @@ describe('@boost - Boost', () => {
// check Activity
await elementById('BoostingIcon').waitForDisplayed();
await elementById('ActivityShort-0').waitForDisplayed();

// no additional boost tx item on iOS, there is one on Android
// https://github.com/synonymdev/bitkit-android/issues/463
const showsBoostTxItem = driver.isAndroid;
if (showsBoostTxItem) {
await expect(elementById('ActivityShort-1')).toBeDisplayed();
await expect(elementById('ActivityShort-2')).not.toBeDisplayed();
} else {
await expect(elementById('ActivityShort-1')).not.toBeDisplayed();
await expect(elementById('ActivityShort-2')).not.toBeDisplayed();
}
await elementById('ActivityShort-1').waitForDisplayed();
await expect(elementById('ActivityShort-2')).not.toBeDisplayed();
await expectTextWithin('ActivityShort-0', '-');
await expectTextWithin('ActivityShort-0', 'Boost Fee');
await expectTextWithin('ActivityShort-1', '100 000');
await expectTextWithin('ActivityShort-1', '+');

// orig tx still there
await swipeFullScreen('up');
if (showsBoostTxItem) {
await tap('ActivityShort-1');
} else {
await tap('ActivityShort-0');
}
await tap('ActivityShort-1');
await expectText('100 000', { strategy: 'contains' });
await elementById('BoostedButton').waitForDisplayed();
await elementById('StatusBoosting').waitForDisplayed();
Expand All @@ -111,17 +101,14 @@ describe('@boost - Boost', () => {
console.info({ parentTxId });
await doNavigationClose();

if (showsBoostTxItem) {
// new tx
await tap('ActivityShort-0');
await tap('ActivityTxDetails');
const boostTxId = await getTextUnder('TXID');
console.info({ newTxId: boostTxId });
await expect(origTxId !== boostTxId).toBe(true);
// TODO: not implemented yet
// await expect(boostTxId === parentTxId).toBe(true);
await doNavigationClose();
}
// new tx: Boost Fee
await tap('ActivityShort-0');
await tap('ActivityTxDetails');
const boostTxId = await getTextUnder('TXID');
console.info({ newTxId: boostTxId });
await expect(origTxId !== boostTxId).toBe(true);
await expect(boostTxId === parentTxId).toBe(true);
await doNavigationClose();

// wipe & restore
const seed = await getSeed();
Expand All @@ -131,39 +118,25 @@ describe('@boost - Boost', () => {
// check activity after restore
await swipeFullScreen('up');
await elementById('BoostingIcon').waitForDisplayed();
if (showsBoostTxItem) {
await elementById('ActivityShort-1').waitForDisplayed();
await tap('ActivityShort-1');
} else {
await elementById('ActivityShort-0').waitForDisplayed();
await tap('ActivityShort-0');
}
await elementById('ActivityShort-1').waitForDisplayed();
await tap('ActivityShort-1');
await elementById('BoostedButton').waitForDisplayed();
await elementById('StatusBoosting').waitForDisplayed();

// mine new block
await mineBlocks(rpc, 1);

// check activity item after mine
// TEMP: refresh until proper events available
await doNavigationClose();
await sleep(500);
await swipeFullScreen('down');
await attemptRefreshOnHomeScreen();
await swipeFullScreen('up');

// check activity item after mine
await elementById('ActivityShort-0').waitForDisplayed();
if (showsBoostTxItem) {
await elementById('ActivityShort-1').waitForDisplayed();
}
// TEMP: refresh until proper events available
await elementById('ActivityShort-1').waitForDisplayed();

await tap('ActivityShort-0');
await elementById('StatusConfirmed').waitForDisplayed();
await doNavigationClose();
if (showsBoostTxItem) {
await tap('ActivityShort-1');
await elementById('StatusConfirmed').waitForDisplayed();
}
await tap('ActivityShort-1');
await elementById('StatusConfirmed').waitForDisplayed();
});

ciIt('@boost_2 - Can do RBF', async () => {
Expand Down Expand Up @@ -233,11 +206,10 @@ describe('@boost - Boost', () => {
await elementById('BoostingIcon').waitForDisplayed();
await elementById('ActivityShort-0').waitForDisplayed();
await elementById('ActivityShort-1').waitForDisplayed();
await elementById('ActivityShort-2').waitForDisplayed();
await expect(elementById('ActivityShort-2')).not.toBeDisplayed();
await expectTextWithin('ActivityShort-0', '-');
await expectTextWithin('ActivityShort-1', '-');
await expectTextWithin('ActivityShort-2', '100 000');
await expectTextWithin('ActivityShort-2', '+');
await expectTextWithin('ActivityShort-1', '100 000');
await expectTextWithin('ActivityShort-1', '+');

// new tx
await tap('ActivityShort-0');
Expand All @@ -262,32 +234,20 @@ describe('@boost - Boost', () => {
// check activity after restore
await swipeFullScreen('up');
(await elementByIdWithin('ActivityShort-0', 'BoostingIcon')).waitForDisplayed();
(await elementByIdWithin('ActivityShort-1', 'BoostingIcon')).waitForDisplayed();
await tap('ActivityShort-0');
await elementById('BoostedButton').waitForDisplayed();
await elementById('StatusBoosting').waitForDisplayed();
await doNavigationClose();
await tap('ActivityShort-1');
await elementById('BoostedButton').waitForDisplayed();
await elementById('StatusRemoved').waitForDisplayed();

// mine new block
await mineBlocks(rpc, 1);

// check activity item after mine
// TEMP: refresh until proper events available
await doNavigationClose();
await sleep(500);
await swipeFullScreen('down');
await attemptRefreshOnHomeScreen();
await swipeFullScreen('up');
// TEMP: refresh until proper events available

// check activity item after mine
await elementById('ActivityShort-0').waitForDisplayed();
await tap('ActivityShort-0');
await elementById('StatusConfirmed').waitForDisplayed();
await doNavigationClose();
(await elementByIdWithin('ActivityShort-1', 'BoostingIcon')).waitForDisplayed();
await tap('ActivityShort-1');
await elementById('StatusRemoved').waitForDisplayed();
});
});
Loading