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
4 changes: 4 additions & 0 deletions Gem.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
B6B86A102D702E7C00D31D65 /* SwapNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B86A0F2D702E7C00D31D65 /* SwapNavigationView.swift */; };
B6C8F2AF2EDE2691005915E4 /* UITestKitConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C8F2AD2EDE2691005915E4 /* UITestKitConstants.swift */; };
B6CBBC552ED9A80B0043443B /* CreateWalletUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CBBC542ED9A80B0043443B /* CreateWalletUITests.swift */; };
B6D1A0012EE3000000UPGRADE /* UpgradeVerificationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D1A0002EE3000000UPGRADE /* UpgradeVerificationTests.swift */; };
B6STREAM02F5000000000001 /* StreamService in Frameworks */ = {isa = PBXBuildFile; productRef = B6STREAM02F5000000000002 /* StreamService */; };
C30952B4299C39D70004C0F9 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C30952B3299C39D70004C0F9 /* App.swift */; };
C34C7CF829FDE942009EEC21 /* unit_frameworks.xctestplan in Resources */ = {isa = PBXBuildFile; fileRef = C34C7CF729FDE942009EEC21 /* unit_frameworks.xctestplan */; };
Expand Down Expand Up @@ -226,6 +227,7 @@
B6B86A0F2D702E7C00D31D65 /* SwapNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwapNavigationView.swift; sourceTree = "<group>"; };
B6C8F2AD2EDE2691005915E4 /* UITestKitConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestKitConstants.swift; sourceTree = "<group>"; };
B6CBBC542ED9A80B0043443B /* CreateWalletUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateWalletUITests.swift; sourceTree = "<group>"; };
B6D1A0002EE3000000UPGRADE /* UpgradeVerificationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeVerificationTests.swift; sourceTree = "<group>"; };
B6EA21D42E27E21700F1C849 /* Support */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = Support; sourceTree = "<group>"; };
C30952B0299C39D70004C0F9 /* Gem.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Gem.app; sourceTree = BUILT_PRODUCTS_DIR; };
C30952B3299C39D70004C0F9 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -567,6 +569,7 @@
B68058302ED9C6F7001273D6 /* Extensions */,
B69D9C852ED85EA000A04F7F /* ImportWalletReceiveBitcoinUITests.swift */,
B6CBBC542ED9A80B0043443B /* CreateWalletUITests.swift */,
B6D1A0002EE3000000UPGRADE /* UpgradeVerificationTests.swift */,
);
path = GemUITestsAppTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -1169,6 +1172,7 @@
files = (
B69D9C872ED85EA000A04F7F /* ImportWalletReceiveBitcoinUITests.swift in Sources */,
B6CBBC552ED9A80B0043443B /* CreateWalletUITests.swift in Sources */,
B6D1A0012EE3000000UPGRADE /* UpgradeVerificationTests.swift in Sources */,
B68058312ED9C6F7001273D6 /* XCTestCase+GemUITestsAppTests.swift in Sources */,
B6C8F2AF2EDE2691005915E4 /* UITestKitConstants.swift in Sources */,
B68058322ED9C6F7001273D6 /* XCUIApplication+GemUITestsAppTests.swift in Sources */,
Expand Down
42 changes: 42 additions & 0 deletions GemUITestsAppTests/UpgradeVerificationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c). Gem Wallet. All rights reserved.

import XCTest

@MainActor
final class UpgradeVerificationTests: XCTestCase {

override func setUpWithError() throws {
try super.setUpWithError()
continueAfterFailure = false
}

func testWalletSurvivedUpgrade() throws {
let app = XCUIApplication()
setupPermissionHandler()
app.launch()

XCTAssertFalse(app.isOnboarding, "App should not show onboarding after upgrade — wallet data was lost")

// Navigate to wallet detail
app.buttons["Wallet"].firstMatch.tap()
app.tapWalletBar()

// WalletsScene
let gearButton = app.buttons["gearshape"].firstMatch
XCTAssertTrue(gearButton.waitForExistence(timeout: 10), "No wallets found after upgrade")
gearButton.tap()

// WalletDetailScene
let showPhraseButton = app.buttons["Show Secret Phrase"].firstMatch
XCTAssertTrue(showPhraseButton.waitForExistence(timeout: 10), "Show Secret Phrase not found")
showPhraseButton.tap()

// SecurityReminderScene
app.tapContinue()

// ShowSecretDataScene
let expectedWords = UITestKitConstants.words.components(separatedBy: " ")
let displayedWords = app.getWords()
XCTAssertEqual(displayedWords, expectedWords, "Secret phrase mismatch after upgrade — keys were corrupted")
}
}
74 changes: 74 additions & 0 deletions build-system/scripts/upgrade-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -euo pipefail

COMMIT="${1:?Usage: just upgrade-test <commit-or-tag>}"
REPO_ROOT="$(git rev-parse --show-toplevel)"
WORKTREE_DIR="/tmp/gem-upgrade-test-$$"
SIMULATOR_NAME="${SIMULATOR_NAME:-iPhone 17}"
SIMULATOR_DEST="platform=iOS Simulator,name=$SIMULATOR_NAME"
OLD_DERIVED_DATA="$WORKTREE_DIR/build/DerivedData"

cleanup() {
echo "==> Cleaning up worktree"
cd "$REPO_ROOT"
git worktree remove --force "$WORKTREE_DIR" 2>/dev/null || true
}
trap cleanup EXIT

echo "==> Phase 1: Build old version ($COMMIT)"

git worktree add "$WORKTREE_DIR" "$COMMIT"
cd "$WORKTREE_DIR"
git submodule update --init

echo "==> Generating stone (old)"
just generate-stone

echo "==> Building old version for UI testing"
set -o pipefail && xcodebuild -project Gem.xcodeproj \
-scheme GemUITests \
-testPlan ui_tests \
ONLY_ACTIVE_ARCH=YES \
-destination "$SIMULATOR_DEST" \
-derivedDataPath "$OLD_DERIVED_DATA" \
-allowProvisioningUpdates \
-allowProvisioningDeviceRegistration \
build-for-testing | xcbeautify --quieter --is-ci

echo "==> Resetting simulator"
cd "$REPO_ROOT"
just reset-simulator

echo "==> Running ImportWalletReceiveBitcoinUITests (old version)"
cd "$WORKTREE_DIR"
set -o pipefail && xcodebuild -project Gem.xcodeproj \
-scheme GemUITests \
-testPlan ui_tests \
ONLY_ACTIVE_ARCH=YES \
-destination "$SIMULATOR_DEST" \
-derivedDataPath "$OLD_DERIVED_DATA" \
-allowProvisioningUpdates \
-allowProvisioningDeviceRegistration \
-only-testing GemUITests/ImportWalletReceiveBitcoinUITests \
test-without-building | xcbeautify --quieter --is-ci

echo "==> Phase 2: Build current version"
cd "$REPO_ROOT"

just build-for-testing-ui

DERIVED_DATA="build/DerivedData"

echo "==> Running UpgradeVerificationTests (current version)"
set -o pipefail && xcodebuild -project Gem.xcodeproj \
-scheme GemUITests \
-testPlan ui_tests \
ONLY_ACTIVE_ARCH=YES \
-destination "$SIMULATOR_DEST" \
-derivedDataPath "$DERIVED_DATA" \
-allowProvisioningUpdates \
-allowProvisioningDeviceRegistration \
-only-testing GemUITests/UpgradeVerificationTests \
test-without-building | xcbeautify --quieter --is-ci

echo "==> Upgrade test passed!"
4 changes: 4 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ build-for-testing-ui: (_test-ui "build-for-testing")

test-ui-without-building: reset-simulator (_test-ui "test-without-building")

# Run full upgrade test: build old version, create wallet, build current, verify wallet survives
test-upgrade COMMIT:
@bash build-system/scripts/upgrade-test.sh {{COMMIT}}

reset-simulator NAME=SIMULATOR_NAME:
@echo "==> Resetting {{NAME}} simulator to clean state"
@xcrun simctl shutdown "{{NAME}}" 2>/dev/null || true
Expand Down
Loading