Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,4 @@ Implication for feature work:
- The tests expect built artifacts in `./aut`.
- Use `ciIt()` in specs (not `it()`) to enable CI retry-skipping behavior.
- Keep Android/iOS platform differences behind helpers in `test/helpers/`.
- Prefer extracting shared flows into `test/helpers/` over copying logic between specs. Keep helpers small and reuse existing ones before adding new test code.
18 changes: 13 additions & 5 deletions scripts/build-android-apk.sh
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
#!/usr/bin/env bash
# Build the Bitkit Android dev debug APK from ../bitkit-android and copy into aut/
# Build the Bitkit Android debug APK from ../bitkit-android and copy into aut/
#
# Inputs/roots:
# - E2E root: this repo (bitkit-e2e-tests)
# - Android root: ../bitkit-android (resolved relative to this script)
#
# Output:
# - Copies dev debug APK -> aut/bitkit_e2e.apk
# - Copies dev/regtest debug APK -> aut/bitkit_e2e.apk
# - Copies mainnet debug APK -> aut/bitkit_e2e_mainnet.apk
#
# Requirements:
# - Android SDK/NDK as required by the project, Gradle wrapper
#
# Usage:
# ./scripts/build-android-apk.sh
# BACKEND=regtest ./scripts/build-android-apk.sh
# BACKEND=mainnet ./scripts/build-android-apk.sh
set -euo pipefail

E2E_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
Expand All @@ -23,16 +25,22 @@ BACKEND="${BACKEND:-local}"
E2E_BACKEND="local"
GRADLE_TASK="assembleDevDebug"
APK_FLAVOR_DIR="dev/debug"
OUT_FILENAME="bitkit_e2e.apk"

if [[ "$BACKEND" == "regtest" ]]; then
E2E_BACKEND="network"
elif [[ "$BACKEND" == "local" ]]; then
E2E_BACKEND="local"
elif [[ "$BACKEND" == "mainnet" ]]; then
E2E_BACKEND="network"
GRADLE_TASK="assembleMainnetDebug"
APK_FLAVOR_DIR="mainnet/debug"
OUT_FILENAME="bitkit_e2e_mainnet.apk"
else
echo "ERROR: Unsupported BACKEND value: $BACKEND" >&2
exit 1
fi
echo "Building Android APK (BACKEND=$BACKEND, E2E_BACKEND=$E2E_BACKEND)..."
echo "Building Android APK (BACKEND=$BACKEND, E2E_BACKEND=$E2E_BACKEND, GRADLE_TASK=$GRADLE_TASK)..."

pushd "$ANDROID_ROOT" >/dev/null
E2E=true E2E_BACKEND="$E2E_BACKEND" ./gradlew "$GRADLE_TASK" --no-daemon --stacktrace
Expand All @@ -50,5 +58,5 @@ fi

OUT="$E2E_ROOT/aut"
mkdir -p "$OUT"
cp -f "$APK_PATH" "$OUT/bitkit_e2e.apk"
echo "Android APK copied to: $OUT/bitkit_e2e.apk (from $(basename "$APK_PATH"))"
cp -f "$APK_PATH" "$OUT/$OUT_FILENAME"
echo "Android APK copied to: $OUT/$OUT_FILENAME (from $(basename "$APK_PATH"))"
2 changes: 1 addition & 1 deletion test/helpers/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ export async function restoreWallet(

// Wait for Get Started
const getStarted = await elementById('GetStartedButton');
await getStarted.waitForDisplayed({ timeout: 120000 });
await getStarted.waitForDisplayed({ timeout: 180000 });
await tap('GetStartedButton');
await sleep(1000);
if (expectAndroidAlert) {
Expand Down
54 changes: 54 additions & 0 deletions test/helpers/mainnet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {
doNavigationClose,
elementById,
expectTextWithin,
sleep,
tap,
} from './actions';

const WALLET_SYNC_TIMEOUT_MS = 90_000;
const APP_STATUS_ROW_TIMEOUT_MS = 90_000;

type WaitForMainnetWalletReadyOptions = {
logPrefix: string;
};

export async function waitForMainnetWalletReady({
logPrefix,
}: WaitForMainnetWalletReadyOptions): Promise<void> {
console.info(`→ [${logPrefix}] Waiting for wallet home screen...`);
await elementById('TotalBalance-primary').waitForDisplayed({ timeout: WALLET_SYNC_TIMEOUT_MS });

const stabilizeMs = resolveLnStabilizeDelayMs();
console.info(
`→ [${logPrefix}] Home screen ready, letting LN node stabilize (${stabilizeMs / 1000}s)...`
);
await sleep(stabilizeMs);

console.info(`→ [${logPrefix}] Verify app status is ready`);
await tap('HeaderMenu');
await tap('DrawerAppStatus');

await expectTextWithin('Status-internet', 'Connected', { timeout: APP_STATUS_ROW_TIMEOUT_MS });
await expectTextWithin('Status-electrum', 'Connected', { timeout: APP_STATUS_ROW_TIMEOUT_MS });
await expectTextWithin('Status-lightning_node', 'Running', {
timeout: APP_STATUS_ROW_TIMEOUT_MS,
});
await expectTextWithin('Status-lightning_connection', 'Open', {
timeout: APP_STATUS_ROW_TIMEOUT_MS,
});

await doNavigationClose();
console.info(`→ [${logPrefix}] App status verified`);
}

function resolveLnStabilizeDelayMs(): number {
const fromEnv = process.env.LN_STABILIZE_DELAY_MS;
if (fromEnv) {
const parsed = Number.parseInt(fromEnv, 10);
if (Number.isFinite(parsed) && parsed >= 0) {
return parsed;
}
}
return process.env.CI ? 45_000 : 10_000;
}
Loading