Skip to content

Commit 26418c6

Browse files
authored
Merge pull request #422 from synonymdev/test/migration
E2E migration
2 parents 219ffa1 + d96a007 commit 26418c6

4 files changed

Lines changed: 125 additions & 35 deletions

File tree

.github/workflows/e2e_migration.yml

Lines changed: 114 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ on:
77
description: "Branch of synonymdev/bitkit-e2e-tests to use (main | default-feature-branch | custom branch name)"
88
required: false
99
default: "default-feature-branch"
10-
# schedule:
11-
# - cron: "0 2 * * *"
10+
schedule:
11+
- cron: "0 3 * * *"
1212

1313
env:
1414
TERM: xterm-256color
1515
FORCE_COLOR: 1
16+
SIMULATOR_NAME: "iPhone 17"
17+
IOS_VERSION: "26.2"
1618

1719
concurrency:
1820
group: ${{ github.workflow }}-${{ github.ref }}
@@ -27,6 +29,11 @@ jobs:
2729
- name: Checkout
2830
uses: actions/checkout@v4
2931

32+
- name: Set up Xcode
33+
uses: maxim-lobanov/setup-xcode@v1
34+
with:
35+
xcode-version: "26.2"
36+
3037
- name: System Information
3138
run: |
3239
echo "=== System Information ==="
@@ -36,19 +43,42 @@ jobs:
3643
echo "Xcode Version:"
3744
xcodebuild -version
3845
46+
- name: Install xcbeautify
47+
run: |
48+
brew install xcbeautify
49+
50+
- name: Cache Swift Package Manager
51+
uses: actions/cache@v4
52+
with:
53+
path: |
54+
~/Library/Caches/org.swift.swiftpm
55+
~/Library/org.swift.swiftpm
56+
Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm
57+
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
58+
59+
- name: Install dependencies
60+
run: |
61+
echo "⏱️ Starting dependency resolution at $(date)"
62+
xcodebuild -resolvePackageDependencies -onlyUsePackageVersionsFromResolvedFile | xcbeautify
63+
echo "✅ Dependencies resolved at $(date)"
64+
65+
- name: Pre-start simulator
66+
run: |
67+
echo "⏱️ Starting simulator at $(date)"
68+
xcrun simctl boot "${{ env.SIMULATOR_NAME }}" || true
69+
echo "✅ Simulator started at $(date)"
70+
3971
- name: Build iOS app (regtest)
4072
env:
4173
GITHUB_ACTOR: ${{ github.actor }}
4274
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4375
CHATWOOT_API: ${{ secrets.CHATWOOT_API }}
44-
SIMULATOR_NAME: "iPhone 17"
45-
OS_VERSION: "latest"
4676
GEO: false
4777
E2E_BACKEND: network
4878
E2E_NETWORK: regtest
4979
run: |
50-
echo "=== Building iOS app ==="
51-
echo "Using simulator: $SIMULATOR_NAME (iOS $OS_VERSION)"
80+
echo "=== Building iOS app (regtest) ==="
81+
echo "Using simulator: ${{ env.SIMULATOR_NAME }} (iOS ${{ env.IOS_VERSION }})"
5282
5383
if xcodebuild -showsdks | grep -q "iOS Simulator"; then
5484
echo "✅ iOS Simulator platform already installed"
@@ -60,18 +90,19 @@ jobs:
6090
xcodebuild -workspace Bitkit.xcodeproj/project.xcworkspace \
6191
-scheme Bitkit \
6292
-configuration Debug \
63-
-destination "platform=iOS Simulator,name=$SIMULATOR_NAME,OS=$OS_VERSION" \
93+
-destination "platform=iOS Simulator,name=${{ env.SIMULATOR_NAME }},OS=${{ env.IOS_VERSION }}" \
6494
-derivedDataPath DerivedData \
6595
SWIFT_ACTIVE_COMPILATION_CONDITIONS='$(inherited) E2E_BUILD' \
6696
-allowProvisioningUpdates \
6797
build
6898
69-
- name: Prepare app for E2E tests
99+
- name: Prepare app for E2E tests (regtest)
70100
run: |
101+
# Copy the .app bundle to the expected location and name
71102
mkdir -p e2e-app
72103
cp -r DerivedData/Build/Products/Debug-iphonesimulator/Bitkit.app e2e-app/bitkit.app
73104
74-
- name: Upload iOS app
105+
- name: Upload iOS app (regtest)
75106
uses: actions/upload-artifact@v4
76107
with:
77108
name: bitkit-e2e-ios_${{ github.run_number }}
@@ -98,7 +129,7 @@ jobs:
98129
scenario:
99130
- { name: migration_1-restore, setup_type: standard }
100131
- { name: migration_2-migration, setup_type: standard }
101-
- { name: migration_3-with-passphrase, setup_type: standard }
132+
- { name: migration_3-with-passphrase, setup_type: passphrase }
102133
- { name: migration_4-with-sweep, setup_type: sweep }
103134
with:
104135
e2e_branch: ${{ needs.e2e-branch.outputs.branch }}
@@ -119,16 +150,15 @@ jobs:
119150
- v1.1.4
120151
- v1.1.3
121152
scenario:
122-
- { name: migration_1-restore, grep: "@migration_1" }
123-
- { name: migration_2-migration, grep: "@migration_2" }
124-
- { name: migration_3-with-passphrase, grep: "@migration_3" }
125-
- { name: migration_4-with-sweep, grep: "@migration_4" }
153+
- { name: migration_1-restore, setup_type: standard, grep: "@migration_1" }
154+
- { name: migration_2-migration, setup_type: standard, grep: "@migration_2" }
155+
- { name: migration_3-with-passphrase, setup_type: passphrase, grep: "@migration_3" }
156+
- { name: migration_4-with-sweep, setup_type: sweep, grep: "@migration_4" }
126157

127158
name: e2e-tests - ${{ matrix.rn_version }} - ${{ matrix.scenario.name }}
128159

129160
env:
130161
BACKEND: regtest
131-
RN_APK_PATH: bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app
132162

133163
steps:
134164
- name: Show selected E2E branch
@@ -159,11 +189,10 @@ jobs:
159189
working-directory: bitkit-e2e-tests
160190
run: |
161191
set -euo pipefail
162-
if [[ "${{ matrix.scenario.name }}" == "migration_4-with-sweep" ]]; then
163-
env_file="artifacts/migration_setup_sweep.env"
164-
else
165-
env_file="artifacts/migration_setup_standard.env"
166-
fi
192+
env_file="artifacts/migration_setup_${{ matrix.scenario.setup_type }}.env"
193+
echo "=== Env file contents ==="
194+
cat "$env_file"
195+
echo "========================="
167196
cat "$env_file" >> "$GITHUB_ENV"
168197
169198
- name: Download RN app for migration
@@ -172,17 +201,25 @@ jobs:
172201
curl -L -o bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.zip \
173202
https://github.com/synonymdev/bitkit-e2e-tests/releases/download/migration-rn-regtest/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.zip
174203
unzip -o bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.zip -d bitkit-e2e-tests/aut
204+
205+
# Rename the versioned RN app to the expected default name
206+
# (Bitkit.app / bitkit.app is the native app - don't touch it)
207+
if [ -d "bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app" ]; then
208+
mv "bitkit-e2e-tests/aut/bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app" \
209+
"bitkit-e2e-tests/aut/bitkit_rn_regtest_ios.app"
210+
echo "Renamed bitkit_rn_regtest_ios_${{ matrix.rn_version }}.app to bitkit_rn_regtest_ios.app"
211+
fi
175212
176213
- name: List app directory contents
177-
run: ls -l bitkit-e2e-tests/aut
214+
run: ls -la bitkit-e2e-tests/aut
178215

179216
- name: Setup Node.js
180217
uses: actions/setup-node@v4
181218
with:
182219
node-version: 22
183220

184221
- name: Cache npm cache
185-
uses: actions/cache@v3
222+
uses: actions/cache@v4
186223
with:
187224
path: ~/.npm
188225
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -193,27 +230,60 @@ jobs:
193230
working-directory: bitkit-e2e-tests
194231
run: npm ci
195232

196-
- name: Clear previous E2E artifacts
197-
working-directory: bitkit-e2e-tests
233+
- name: Install ffmpeg
198234
run: |
199-
rm -rf artifacts/
200-
rm -rf /tmp/lock/
235+
echo "Installing ffmpeg..."
236+
brew install ffmpeg || brew upgrade ffmpeg || true
237+
echo "ffmpeg version: $(ffmpeg -version | head -1)"
201238
202-
- name: Clear iOS Simulator environment
239+
- name: Boot Simulator
203240
run: |
204-
echo "🔧 Shutting down all running iOS simulators..."
205-
xcrun simctl shutdown all || true
206-
echo "🔧 Erasing target simulator: iPhone 17..."
207-
xcrun simctl erase "iPhone 17" || true
208-
echo "🔧 Disabling iOS Simulator notifications..."
209-
defaults write com.apple.iphonesimulator DisableAllNotifications -bool true
241+
echo "Erasing simulator..."
242+
xcrun simctl erase "${{ env.SIMULATOR_NAME }}" || true
243+
244+
echo "Booting simulator..."
245+
xcrun simctl boot "${{ env.SIMULATOR_NAME }}" || true
246+
247+
echo "Waiting for boot status..."
248+
xcrun simctl bootstatus "${{ env.SIMULATOR_NAME }}" -b
249+
250+
echo "Opening Simulator app to ensure UI is ready..."
251+
open -a Simulator
252+
253+
echo "Waiting for simulator to fully initialize..."
254+
sleep 30
255+
256+
echo "Verifying simulator state..."
257+
xcrun simctl list devices booted
258+
259+
- name: Start Appium Server
260+
working-directory: bitkit-e2e-tests
261+
run: |
262+
echo "Starting Appium server..."
263+
npx appium --log-timestamp --log-no-colors > appium.log 2>&1 &
264+
APPIUM_PID=$!
265+
echo "APPIUM_PID=$APPIUM_PID" >> $GITHUB_ENV
266+
267+
echo "Waiting for Appium server to be ready..."
268+
for i in {1..30}; do
269+
if curl -s http://127.0.0.1:4723/status > /dev/null 2>&1; then
270+
echo "Appium server is ready!"
271+
break
272+
fi
273+
echo "Waiting for Appium... ($i/30)"
274+
sleep 2
275+
done
276+
277+
curl -s http://127.0.0.1:4723/status || echo "Warning: Appium status check failed"
210278
211279
- name: Run E2E Tests 1 (${{ matrix.scenario.name }})
212280
continue-on-error: true
213281
id: test1
214282
working-directory: bitkit-e2e-tests
215283
run: ./ci_run_ios.sh --mochaOpts.grep '${{ matrix.scenario.grep }}'
216284
env:
285+
SIMULATOR_NAME: ${{ env.SIMULATOR_NAME }}
286+
SIMULATOR_OS_VERSION: ${{ env.IOS_VERSION }}
217287
RECORD_VIDEO: true
218288
ATTEMPT: 1
219289

@@ -224,6 +294,8 @@ jobs:
224294
working-directory: bitkit-e2e-tests
225295
run: ./ci_run_ios.sh --mochaOpts.grep "${{ matrix.scenario.grep }}"
226296
env:
297+
SIMULATOR_NAME: ${{ env.SIMULATOR_NAME }}
298+
SIMULATOR_OS_VERSION: ${{ env.IOS_VERSION }}
227299
RECORD_VIDEO: true
228300
ATTEMPT: 2
229301

@@ -233,9 +305,18 @@ jobs:
233305
working-directory: bitkit-e2e-tests
234306
run: ./ci_run_ios.sh --mochaOpts.grep "${{ matrix.scenario.grep }}"
235307
env:
308+
SIMULATOR_NAME: ${{ env.SIMULATOR_NAME }}
309+
SIMULATOR_OS_VERSION: ${{ env.IOS_VERSION }}
236310
RECORD_VIDEO: true
237311
ATTEMPT: 3
238312

313+
- name: Copy Appium logs to artifacts
314+
if: always()
315+
working-directory: bitkit-e2e-tests
316+
run: |
317+
mkdir -p artifacts
318+
cp appium.log artifacts/ || true
319+
239320
- name: Upload E2E Artifacts (${{ matrix.scenario.name }})
240321
if: failure()
241322
uses: actions/upload-artifact@v4

Bitkit/Components/SheetIntro.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ struct SheetIntro: View {
1010
let accentColor: Color
1111
let accentFont: ((CGFloat) -> Font)?
1212
let testID: String?
13+
let continueTestID: String?
1314
let onCancel: (() -> Void)?
1415
let onContinue: () -> Void
1516
private var baseTestID: String {
@@ -26,6 +27,7 @@ struct SheetIntro: View {
2627
accentColor: Color = .brandAccent,
2728
accentFont: ((CGFloat) -> Font)? = nil,
2829
testID: String? = nil,
30+
continueTestID: String? = nil,
2931
onCancel: (() -> Void)? = nil,
3032
onContinue: @escaping () -> Void
3133
) {
@@ -38,6 +40,7 @@ struct SheetIntro: View {
3840
self.accentColor = accentColor
3941
self.accentFont = accentFont
4042
self.testID = testID
43+
self.continueTestID = continueTestID
4144
self.onCancel = onCancel
4245
self.onContinue = onContinue
4346
}
@@ -74,6 +77,10 @@ struct SheetIntro: View {
7477
.accessibilityIdentifier(baseTestID)
7578
}
7679

80+
private var continueButtonTestID: String {
81+
continueTestID ?? "\(baseTestID)Continue"
82+
}
83+
7784
@ViewBuilder
7885
private var buttonStack: some View {
7986
if let cancelText, let onCancel {
@@ -91,15 +98,15 @@ struct SheetIntro: View {
9198
) {
9299
onContinue()
93100
}
94-
.accessibilityIdentifier("\(baseTestID)Continue")
101+
.accessibilityIdentifier(continueButtonTestID)
95102
}
96103
} else {
97104
CustomButton(
98105
title: continueText
99106
) {
100107
onContinue()
101108
}
102-
.accessibilityIdentifier("\(baseTestID)Continue")
109+
.accessibilityIdentifier(continueButtonTestID)
103110
}
104111
}
105112
}

Bitkit/Views/Settings/Advanced/SweepPromptSheet.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct SweepPromptSheet: View {
2020
continueText: t("sweep__prompt_sweep"),
2121
cancelText: t("common__cancel"),
2222
testID: "SweepPromptSheet",
23+
continueTestID: "SweepButton",
2324
onCancel: {
2425
sheets.hideSheet()
2526
},

Bitkit/Views/Settings/Advanced/SweepSettingsView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ struct SweepSettingsView: View {
125125
CustomButton(title: t("sweep__sweep_to_wallet")) {
126126
navigation.navigate(.sweepConfirm)
127127
}
128+
.accessibilityIdentifier("SweepToWalletButton")
128129
}
129130
}
130131

0 commit comments

Comments
 (0)