Skip to content

Commit 426889a

Browse files
authored
Merge pull request #116 from synonymdev/test/migration
Test/migration 2
2 parents f52583a + 2a06205 commit 426889a

5 files changed

Lines changed: 75 additions & 39 deletions

File tree

.github/workflows/migration-wallet-setup.yml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ on:
1313
type: string
1414
default: "v1.1.6"
1515
setup_type:
16-
description: "Wallet setup type (standard | sweep)"
16+
description: "Wallet setup type (standard | passphrase | sweep)"
1717
required: true
1818
type: string
1919
scenario_name:
@@ -72,6 +72,7 @@ jobs:
7272
working-directory: bitkit-e2e-tests
7373
run: |
7474
rm -f artifacts/migration_setup_standard.env
75+
rm -f artifacts/migration_setup_passphrase.env
7576
rm -f artifacts/migration_setup_sweep.env
7677
7778
- name: Prepare migration wallet 1
@@ -85,7 +86,7 @@ jobs:
8586
avd-name: Pixel_6
8687
force-avd-creation: false
8788
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-front none
88-
script: cd bitkit-e2e-tests && ./ci_run_android.sh --mochaOpts.grep "${{ inputs.setup_type == 'sweep' && '@migration_setup_sweep' || '@migration_setup_standard' }}"
89+
script: cd bitkit-e2e-tests && ./ci_run_android.sh --mochaOpts.grep "@migration_setup_${{ inputs.setup_type }}"
8990
env:
9091
BACKEND: regtest
9192

@@ -101,7 +102,7 @@ jobs:
101102
avd-name: Pixel_6
102103
force-avd-creation: false
103104
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-front none
104-
script: cd bitkit-e2e-tests && ./ci_run_android.sh --mochaOpts.grep "${{ inputs.setup_type == 'sweep' && '@migration_setup_sweep' || '@migration_setup_standard' }}"
105+
script: cd bitkit-e2e-tests && ./ci_run_android.sh --mochaOpts.grep "@migration_setup_${{ inputs.setup_type }}"
105106
env:
106107
BACKEND: regtest
107108

@@ -116,18 +117,14 @@ jobs:
116117
avd-name: Pixel_6
117118
force-avd-creation: false
118119
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-front none
119-
script: cd bitkit-e2e-tests && ./ci_run_android.sh --mochaOpts.grep "${{ inputs.setup_type == 'sweep' && '@migration_setup_sweep' || '@migration_setup_standard' }}"
120+
script: cd bitkit-e2e-tests && ./ci_run_android.sh --mochaOpts.grep "@migration_setup_${{ inputs.setup_type }}"
120121
env:
121122
BACKEND: regtest
122123

123124
- name: Verify migration env file
124125
run: |
125126
set -euo pipefail
126-
if [[ "${{ inputs.setup_type }}" == "sweep" ]]; then
127-
test -f bitkit-e2e-tests/artifacts/migration_setup_sweep.env
128-
else
129-
test -f bitkit-e2e-tests/artifacts/migration_setup_standard.env
130-
fi
127+
test -f "bitkit-e2e-tests/artifacts/migration_setup_${{ inputs.setup_type }}.env"
131128
132129
- name: Upload migration env file
133130
uses: actions/upload-artifact@v4

test/helpers/actions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,11 +541,13 @@ export async function restoreWallet(
541541
passphrase,
542542
expectQuickPayTimedSheet = false,
543543
expectBackupSheet = false,
544+
expectBackGroundPaymentsSheet = false,
544545
reinstall = true,
545546
}: {
546547
passphrase?: string;
547548
expectQuickPayTimedSheet?: boolean;
548549
expectBackupSheet?: boolean;
550+
expectBackGroundPaymentsSheet?: boolean;
549551
reinstall?: boolean;
550552
} = {}
551553
) {
@@ -603,6 +605,10 @@ export async function restoreWallet(
603605
await dismissQuickPayIntro();
604606
}
605607

608+
if (expectBackGroundPaymentsSheet) {
609+
await dismissBackgroundPaymentsTimedSheet();
610+
}
611+
606612
// Wait for Suggestions Label to appear
607613
const suggestions = await elementById('Suggestions');
608614
await suggestions.waitForDisplayed();

test/helpers/constants.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export function getBackend(): Backend {
3131
return backend;
3232
}
3333

34-
export const electrumHost = getBackend() === 'regtest' ? 'electrs.bitkit.stag0.blocktank.to' : '127.0.0.1';
34+
export const electrumHost =
35+
getBackend() === 'regtest' ? 'electrs.bitkit.stag0.blocktank.to' : '127.0.0.1';
3536
export const electrumPort = getBackend() === 'regtest' ? 9999 : 60001;
3637

3738
// Blocktank API for regtest operations (deposit, mine blocks, pay invoices)

test/specs/migration.e2e.ts

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,11 @@ const TEST_PASSPHRASE = 'supersecret';
6262
// iOS: Read mnemonic and balance from env vars (prepared by Android run)
6363
// This is needed because RN app on iOS has poor Appium support
6464
// Strip quotes if present (GITHUB_ENV format shouldn't have them, but be defensive)
65-
const stripQuotes = (s: string | undefined): string | undefined =>
66-
s?.replace(/^["']|["']$/g, '');
65+
const stripQuotes = (s: string | undefined): string | undefined => s?.replace(/^["']|["']$/g, '');
6766
const IOS_RN_MNEMONIC = stripQuotes(process.env.RN_MNEMONIC);
6867
const IOS_RN_BALANCE = process.env.RN_BALANCE
6968
? parseInt(stripQuotes(process.env.RN_BALANCE)!, 10)
7069
: undefined;
71-
const IOS_RN_MNEMONIC_SWEEP = stripQuotes(process.env.RN_MNEMONIC_SWEEP);
72-
const IOS_RN_BALANCE_SWEEP = process.env.RN_BALANCE_SWEEP
73-
? parseInt(stripQuotes(process.env.RN_BALANCE_SWEEP)!, 10)
74-
: undefined;
7570

7671
// ============================================================================
7772
// TEST SUITE
@@ -96,32 +91,55 @@ describe('@migration - Migration from legacy RN app to native app', () => {
9691
}
9792

9893
const { mnemonic, balance } = await setupLegacyWallet({ returnSeed: true });
99-
console.info('→ Waiting 60 seconds to ensure backups triggered...');
100-
await sleep(60000);
10194
writeMigrationEnvFile({
10295
fileName: 'migration_setup_standard.env',
10396
mnemonicVar: 'RN_MNEMONIC',
10497
balanceVar: 'RN_BALANCE',
10598
mnemonic,
10699
balance,
107100
});
101+
console.info('→ Waiting 20 seconds to ensure backups...');
102+
await sleep(20000);
108103
});
109104

105+
ciIt(
106+
'@migration_setup_passphrase - Prepare legacy wallet with passphrase (Android only)',
107+
async () => {
108+
if (driver.isIOS) {
109+
throw new Error('Migration setup should run on Android only.');
110+
}
111+
112+
const { mnemonic, balance } = await setupLegacyWallet({
113+
returnSeed: true,
114+
passphrase: TEST_PASSPHRASE,
115+
});
116+
writeMigrationEnvFile({
117+
fileName: 'migration_setup_passphrase.env',
118+
mnemonicVar: 'RN_MNEMONIC',
119+
balanceVar: 'RN_BALANCE',
120+
mnemonic,
121+
balance,
122+
});
123+
console.info('→ Waiting 20 seconds to ensure backups...');
124+
await sleep(20000);
125+
}
126+
);
127+
110128
ciIt('@migration_setup_sweep - Prepare legacy sweep wallet (Android only)', async () => {
111129
if (driver.isIOS) {
112130
throw new Error('Migration setup should run on Android only.');
113131
}
114132

115133
const { mnemonic, balance } = await setupWalletWithLegacyFunds({ returnSeed: true });
116-
console.info('→ Waiting 60 seconds to ensure backups triggered...');
117-
await sleep(60000);
118134
writeMigrationEnvFile({
119135
fileName: 'migration_setup_sweep.env',
120-
mnemonicVar: 'RN_MNEMONIC_SWEEP',
121-
balanceVar: 'RN_BALANCE_SWEEP',
136+
mnemonicVar: 'RN_MNEMONIC',
137+
balanceVar: 'RN_BALANCE',
122138
mnemonic,
123139
balance,
124140
});
141+
console.info('→ Waiting 20 seconds to ensure backups...');
142+
await sleep(20000);
125143
});
126144

127145
ciIt('@migration_ios - setupLegacyWallet on iOS', async () => {
@@ -135,8 +153,14 @@ describe('@migration - Migration from legacy RN app to native app', () => {
135153
// Migration Scenario 1: Uninstall RN, install Native, restore mnemonic
136154
// --------------------------------------------------------------------------
137155
ciIt('@migration_1 - Uninstall RN, install Native, restore mnemonic', async () => {
138-
// Setup wallet in RN app and get mnemonic
139-
const { mnemonic, balance } = await setupLegacyWallet({ returnSeed: true });
156+
let mnemonic: string | undefined;
157+
let balance: number;
158+
if (driver.isIOS) {
159+
mnemonic = IOS_RN_MNEMONIC!;
160+
balance = IOS_RN_BALANCE!;
161+
} else {
162+
({ mnemonic, balance } = await setupLegacyWallet({ returnSeed: true }));
163+
}
140164

141165
// Uninstall RN app
142166
console.info('→ Removing legacy RN app...');
@@ -149,7 +173,11 @@ describe('@migration - Migration from legacy RN app to native app', () => {
149173
await driver.activateApp(getAppId());
150174

151175
// Restore wallet with mnemonic (uses custom flow to handle backup sheet)
152-
await restoreWallet(mnemonic!, { reinstall: false, expectBackupSheet: true });
176+
await restoreWallet(mnemonic!, {
177+
reinstall: false,
178+
expectBackupSheet: driver.isAndroid,
179+
expectBackGroundPaymentsSheet: driver.isIOS,
180+
});
153181

154182
// Verify migration
155183
await verifyMigration(balance);
@@ -271,13 +299,19 @@ async function setupLegacyWallet(
271299
'Run Android tests first to prepare the wallet.'
272300
);
273301
}
274-
console.info('=== iOS: Restoring RN wallet from mnemonic (prepared by Android) ===');
275-
console.info(`→ Mnemonic: ${IOS_RN_MNEMONIC.split(' ').slice(0, 3).join(' ')}...`);
302+
console.info(
303+
`=== iOS: Restoring RN wallet from mnemonic (prepared by Android)${passphrase ? ' with passphrase' : ''} ===`
304+
);
305+
console.info(`→ Mnemonic: ${IOS_RN_MNEMONIC}`);
276306
console.info(`→ Expected balance: ${IOS_RN_BALANCE} sats`);
277307

278308
// Install RN app and restore wallet
279309
await installLegacyRnApp();
280-
await restoreRnWallet(IOS_RN_MNEMONIC, { passphrase });
310+
if (passphrase) {
311+
await restoreRnWallet(IOS_RN_MNEMONIC, { passphrase });
312+
} else {
313+
await restoreRnWallet(IOS_RN_MNEMONIC);
314+
}
281315

282316
console.info('=== iOS: RN wallet restored ===');
283317
return { mnemonic: IOS_RN_MNEMONIC, balance: IOS_RN_BALANCE };
@@ -382,23 +416,21 @@ async function setupWalletWithLegacyFunds(
382416
): Promise<LegacyWalletSetupResult> {
383417
const { returnSeed } = options;
384418
if (driver.isIOS) {
385-
if (!IOS_RN_MNEMONIC_SWEEP || !IOS_RN_BALANCE_SWEEP) {
419+
if (!IOS_RN_MNEMONIC || !IOS_RN_BALANCE) {
386420
throw new Error(
387-
'iOS migration sweep tests require RN_MNEMONIC_SWEEP and RN_BALANCE_SWEEP env vars. ' +
421+
'iOS migration tests require RN_MNEMONIC and RN_BALANCE env vars. ' +
388422
'Run Android setup first to prepare the wallet.'
389423
);
390424
}
391425
console.info('=== iOS: Restoring RN sweep wallet from mnemonic (prepared by Android) ===');
392-
console.info(
393-
`→ Mnemonic: ${IOS_RN_MNEMONIC_SWEEP.split(' ').slice(0, 3).join(' ')}...`
394-
);
395-
console.info(`→ Expected balance: ${IOS_RN_BALANCE_SWEEP} sats`);
426+
console.info(`→ Mnemonic: ${IOS_RN_MNEMONIC}`);
427+
console.info(`→ Expected balance: ${IOS_RN_BALANCE} sats`);
396428

397429
await installLegacyRnApp();
398-
await restoreRnWallet(IOS_RN_MNEMONIC_SWEEP);
430+
await restoreRnWallet(IOS_RN_MNEMONIC);
399431

400432
console.info('=== iOS: RN sweep wallet restored ===');
401-
return { mnemonic: IOS_RN_MNEMONIC_SWEEP, balance: IOS_RN_BALANCE_SWEEP };
433+
return { mnemonic: IOS_RN_MNEMONIC, balance: IOS_RN_BALANCE };
402434
}
403435

404436
console.info('=== Setting up wallet with legacy funds (sweep scenario) ===');
@@ -452,7 +484,7 @@ async function handleMigrationFlow({ withSweep = false }): Promise<void> {
452484
try {
453485
await dismissBackupTimedSheet();
454486
} catch {
455-
console.info('→ Could not dismiss backup timed sheet');
487+
console.info('→ Could not dismiss backup timed sheet, trying again...');
456488
await dismissBackupTimedSheet({ triggerTimedSheet: true });
457489
}
458490
}

test/specs/send.e2e.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,11 +530,11 @@ describe('@send - Send', () => {
530530
await doNavigationClose();
531531
await swipeFullScreen('down');
532532
await swipeFullScreen('down');
533-
await tap('ActivitySavings')
533+
await tap('ActivitySavings');
534534
await elementById('Activity-1').waitForDisplayed();
535535
await elementById('Activity-2').waitForDisplayed();
536536
await doNavigationClose();
537-
await tap('ActivitySpending')
537+
await tap('ActivitySpending');
538538
await elementById('Activity-1').waitForDisplayed();
539539
await elementById('Activity-2').waitForDisplayed();
540540
});

0 commit comments

Comments
 (0)