Skip to content

Commit 1bd49e5

Browse files
authored
Merge pull request #91 from synonymdev/feat/rn-migration
Feat/rn migration
2 parents 8a1c534 + 09fdfb0 commit 1bd49e5

File tree

5 files changed

+159
-1
lines changed

5 files changed

+159
-1
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ If you have `bitkit-e2e-tests`, `bitkit-android`, and `bitkit-ios` checked out i
5656
# Android (builds ../bitkit-android and copies APK to ./aut/bitkit_e2e.apk)
5757
./scripts/build-android-apk.sh
5858

59+
# Legacy RN Android (builds ../bitkit and copies APK to ./aut/bitkit_rn_regtest.apk)
60+
./scripts/build-rn-android-apk.sh
61+
5962
# iOS (builds ../bitkit-ios and copies IPA to ./aut/bitkit_e2e.ipa)
6063
./scripts/build-ios-sim.sh
6164
```
@@ -67,6 +70,9 @@ Optional backend selection (`BACKEND=local` is default and can be omitted):
6770
BACKEND=local ./scripts/build-android-apk.sh
6871
BACKEND=regtest ./scripts/build-android-apk.sh
6972

73+
# Legacy RN Android
74+
BACKEND=regtest ./scripts/build-rn-android-apk.sh
75+
7076
# iOS
7177
BACKEND=local ./scripts/build-ios-sim.sh
7278
BACKEND=regtest ./scripts/build-ios-sim.sh

scripts/build-rn-android-apk.sh

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env bash
2+
# Build the legacy Bitkit RN Android APK from ../bitkit and copy into aut/
3+
#
4+
# Inputs/roots:
5+
# - E2E root: this repo (bitkit-e2e-tests)
6+
# - RN root: ../bitkit (resolved relative to this script)
7+
#
8+
# Output:
9+
# - Copies APK -> aut/bitkit_rn_<backend>.apk
10+
#
11+
# Usage:
12+
# ./scripts/build-rn-android-apk.sh [debug|release]
13+
# BACKEND=regtest ./scripts/build-rn-android-apk.sh
14+
# ENV_FILE=.env.test.template ./scripts/build-rn-android-apk.sh
15+
set -euo pipefail
16+
17+
E2E_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
18+
RN_ROOT="$(cd "$E2E_ROOT/../bitkit" && pwd)"
19+
20+
BUILD_TYPE="${1:-debug}"
21+
BACKEND="${BACKEND:-regtest}"
22+
23+
if [[ "$BUILD_TYPE" != "debug" && "$BUILD_TYPE" != "release" ]]; then
24+
echo "ERROR: Unsupported build type: $BUILD_TYPE (expected debug|release)" >&2
25+
exit 1
26+
fi
27+
28+
if [[ -z "${ENV_FILE:-}" ]]; then
29+
if [[ "$BACKEND" == "regtest" ]]; then
30+
ENV_FILE=".env.test.template"
31+
else
32+
ENV_FILE=".env.development"
33+
fi
34+
fi
35+
36+
if [[ ! -f "$RN_ROOT/$ENV_FILE" ]]; then
37+
echo "ERROR: Env file not found: $RN_ROOT/$ENV_FILE" >&2
38+
exit 1
39+
fi
40+
41+
echo "Building RN Android APK (BACKEND=$BACKEND, ENV_FILE=$ENV_FILE, BUILD_TYPE=$BUILD_TYPE)..."
42+
43+
pushd "$RN_ROOT" >/dev/null
44+
if [[ -f .env ]]; then
45+
cp .env .env.bak
46+
fi
47+
cp "$ENV_FILE" .env
48+
E2E_TESTS=true yarn "e2e:build:android-$BUILD_TYPE"
49+
if [[ -f .env.bak ]]; then
50+
mv .env.bak .env
51+
else
52+
rm -f .env
53+
fi
54+
popd >/dev/null
55+
56+
APK_PATH="$RN_ROOT/android/app/build/outputs/apk/$BUILD_TYPE/app-universal-$BUILD_TYPE.apk"
57+
if [[ ! -f "$APK_PATH" ]]; then
58+
ALT_APK_PATH="$RN_ROOT/android/app/build/outputs/apk/$BUILD_TYPE/app-$BUILD_TYPE.apk"
59+
if [[ -f "$ALT_APK_PATH" ]]; then
60+
APK_PATH="$ALT_APK_PATH"
61+
else
62+
echo "ERROR: APK not found at: $APK_PATH" >&2
63+
exit 1
64+
fi
65+
fi
66+
67+
OUT="$E2E_ROOT/aut"
68+
mkdir -p "$OUT"
69+
OUT_APK="$OUT/bitkit_rn_${BACKEND}.apk"
70+
cp -f "$APK_PATH" "$OUT_APK"
71+
echo "RN APK copied to: $OUT_APK (from $(basename "$APK_PATH"))"

test/helpers/actions.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,9 @@ export async function restoreWallet(
565565
const getStarted = await elementById('GetStartedButton');
566566
await getStarted.waitForDisplayed();
567567
await tap('GetStartedButton');
568-
568+
await sleep(1000);
569+
await handleAndroidAlert();
570+
569571
if (expectQuickPayTimedSheet) {
570572
await dismissQuickPayIntro();
571573
}

test/helpers/setup.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { execSync } from 'node:child_process';
2+
import fs from 'node:fs';
3+
import path from 'node:path';
24
import { sleep } from './actions';
35
import { getAppId, getAppPath } from './constants';
46

@@ -24,6 +26,36 @@ export async function reinstallApp() {
2426
await driver.activateApp(appId);
2527
}
2628

29+
export function getRnAppPath(): string {
30+
const fallback = path.join(__dirname, '..', '..', 'aut', 'bitkit_rn_regtest.apk');
31+
const appPath = process.env.RN_APK_PATH ?? fallback;
32+
if (!fs.existsSync(appPath)) {
33+
throw new Error(
34+
`RN APK not found at: ${appPath}. Set RN_APK_PATH or place it at ${fallback}`
35+
);
36+
}
37+
return appPath;
38+
}
39+
40+
export function getNativeAppPath(): string {
41+
const fallback = path.join(__dirname, '..', '..', 'aut', 'bitkit_e2e.apk');
42+
const appPath = process.env.NATIVE_APK_PATH ?? fallback;
43+
if (!fs.existsSync(appPath)) {
44+
throw new Error(
45+
`Native APK not found at: ${appPath}. Set NATIVE_APK_PATH or place it at ${fallback}`
46+
);
47+
}
48+
return appPath;
49+
}
50+
51+
export async function reinstallAppFromPath(appPath: string, appId: string = getAppId()) {
52+
console.info(`→ Reinstalling app from: ${appPath}`);
53+
await driver.removeApp(appId);
54+
resetBootedIOSKeychain();
55+
await driver.installApp(appPath);
56+
await driver.activateApp(appId);
57+
}
58+
2759
/**
2860
* Resets iOS simulator to remove stored data between app reinstall cycles.
2961
* (Wallet data is stored in iOS Keychain and persists even after app uninstall

test/specs/migration.e2e.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { elementById, restoreWallet, sleep, tap, typeText, waitForSetupWalletScreenFinish } from '../helpers/actions';
2+
import { ciIt } from '../helpers/suite';
3+
import { getNativeAppPath, getRnAppPath, reinstallAppFromPath } from '../helpers/setup';
4+
5+
const MIGRATION_MNEMONIC =
6+
process.env.MIGRATION_MNEMONIC ??
7+
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
8+
9+
describe('@migration - Legacy RN migration', () => {
10+
ciIt('@migration_1 - Can restore legacy RN wallet from mnemonic', async () => {
11+
await installLegacyRnApp();
12+
await restoreLegacyRnWallet(MIGRATION_MNEMONIC);
13+
14+
// Restore into native app
15+
// await installNativeApp();
16+
await restoreWallet(MIGRATION_MNEMONIC);
17+
});
18+
});
19+
20+
async function installNativeApp() {
21+
await reinstallAppFromPath(getNativeAppPath());
22+
}
23+
async function installLegacyRnApp() {
24+
await reinstallAppFromPath(getRnAppPath());
25+
}
26+
27+
async function restoreLegacyRnWallet(seed: string) {
28+
await elementById('Continue').waitForDisplayed();
29+
await tap('Check1');
30+
await tap('Check2');
31+
await tap('Continue');
32+
33+
await tap('SkipIntro');
34+
35+
await tap('RestoreWallet');
36+
await tap('MultipleDevices-button');
37+
38+
await typeText('Word-0', seed);
39+
await sleep(1500);
40+
await tap('RestoreButton');
41+
await waitForSetupWalletScreenFinish();
42+
43+
const getStarted = await elementById('GetStartedButton');
44+
await getStarted.waitForDisplayed( { timeout: 120000 });
45+
await tap('GetStartedButton');
46+
await sleep(1000);
47+
}

0 commit comments

Comments
 (0)