Skip to content
Merged
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
8 changes: 4 additions & 4 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ jobs:
# - { name: onchain_boost_receive_widgets, grep: "@onchain|@boost|@receive|@widgets" }
# - { name: settings, grep: "@settings" }
# - { name: security, grep: "@security" }
- { name: e2e, grep: '^(?!.*@settings_10)(@backup|@onboarding|@onchain_1|@onchain_2|@numberpad|@widgets|@boost|@receive|@settings|@security)' }
- { name: e2e, grep: '@backup|@onboarding|@onchain_1|@onchain_2|@numberpad|@widgets|@boost|@receive|@settings|@security' }

name: e2e-tests - ${{ matrix.shard.name }}

Expand Down Expand Up @@ -175,15 +175,15 @@ jobs:
working-directory: bitkit-e2e-tests
run: |
echo "Waiting for Electrum server..."
while ! nc -z '127.0.0.1' 60001; do
while ! nc -z '127.0.0.1' 60001; do
echo "Electrum server not ready, waiting..."
sleep 5
done
echo "Electrum server is ready!"

- name: Clear previous E2E artifacts
working-directory: bitkit-e2e-tests
run: |
run: |
rm -rf artifacts/
rm -rf /tmp/lock/

Expand Down Expand Up @@ -249,4 +249,4 @@ jobs:
echo "❌ Some E2E shards failed."
exit 1
fi
echo "✅ All E2E shards passed!"
echo "✅ All E2E shards passed!"
1 change: 1 addition & 0 deletions Bitkit/Components/TabBar/ScanButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct ScanButton: View {
.background(Circle().fill(background))
.foregroundColor(.gray1)
}
.accessibilityIdentifier("Scan")
.shadow(color: Color.gray2, radius: 0, x: 0, y: -1)
.shadow(color: Color.black.opacity(0.25), radius: 25, x: 0, y: 20)
.overlay(
Expand Down
14 changes: 14 additions & 0 deletions Bitkit/Managers/ScannerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,18 @@ class ScannerManager: ObservableObject {
)
}
}

func handleManualEntry(
_ value: String,
context: ScannerContext,
onSuccess: @MainActor () -> Void
) async {
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return }

await handleScan(trimmed, context: context)
await MainActor.run {
onSuccess()
}
}
}
41 changes: 41 additions & 0 deletions Bitkit/Views/Scanner/ManualScanPrompt.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import SwiftUI

struct ScannerManualEntryPrompt: View {
@Binding var text: String
var onSubmit: () -> Void
var onCancel: () -> Void

var body: some View {
VStack(alignment: .leading, spacing: 16) {
HStack {
Spacer()
Button(action: onCancel) {
Image("x-mark")
.resizable()
.frame(width: 16, height: 16)
}
.accessibilityIdentifier("DialogCancel")
}

BodyMSBText("Enter QR Code String")

SwiftUI.TextField("", text: $text)
.textInputAutocapitalization(.never)
.autocorrectionDisabled()
.padding()
.background(Color.white10)
.cornerRadius(10)
.accessibilityIdentifier("QRInput")

CustomButton(title: t("common__yes_proceed"), shouldExpand: true) {
onSubmit()
}
.accessibilityIdentifier("DialogConfirm")

Spacer()
}
.padding(16)
.accessibilityElement(children: .contain)
.accessibilityIdentifier("QRDialog")
}
}
37 changes: 37 additions & 0 deletions Bitkit/Views/Scanner/ScannerScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ struct ScannerScreen: View {
@EnvironmentObject private var scanner: ScannerManager
@EnvironmentObject private var settings: SettingsViewModel
@EnvironmentObject private var sheets: SheetViewModel
@State private var isManualEntryPresented = false
@State private var manualEntry = ""

private var scannerContext: ScannerContext {
if navigation.path.contains(.electrumSettings) {
Expand Down Expand Up @@ -39,6 +41,19 @@ struct ScannerScreen: View {
) {
await scanner.handlePaste(context: scannerContext)
}
.padding(.bottom, Env.isE2E ? 12 : 0)

if Env.isE2E {
CustomButton(
title: "Enter QR Code String",
variant: .secondary,
shouldExpand: true
) {
manualEntry = ""
isManualEntryPresented = true
}
.accessibilityIdentifier("ScanPrompt")
}
}
.navigationBarHidden(true)
.padding(.horizontal, 16)
Expand All @@ -52,5 +67,27 @@ struct ScannerScreen: View {
sheets: sheets
)
}
.sheet(isPresented: $isManualEntryPresented) {
ScannerManualEntryPrompt(
text: $manualEntry,
onSubmit: {
Task {
await handleManualEntrySubmit()
}
},
onCancel: {
isManualEntryPresented = false
}
)
.presentationDetents([.fraction(0.35)])
.presentationDragIndicator(.visible)
}
}

private func handleManualEntrySubmit() async {
await scanner.handleManualEntry(manualEntry, context: scannerContext) {
isManualEntryPresented = false
manualEntry = ""
}
}
}
37 changes: 37 additions & 0 deletions Bitkit/Views/Scanner/ScannerSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ struct ScannerSheet: View {
@EnvironmentObject private var scanner: ScannerManager
@EnvironmentObject private var settings: SettingsViewModel
@EnvironmentObject private var sheets: SheetViewModel
@State private var isManualEntryPresented = false
@State private var manualEntry = ""

let config: ScannerSheetItem

Expand Down Expand Up @@ -40,6 +42,19 @@ struct ScannerSheet: View {
) {
await scanner.handlePaste(context: .main)
}

if Env.isE2E {
CustomButton(
title: "Enter QRCode String",
variant: .secondary,
shouldExpand: true
) {
manualEntry = ""
isManualEntryPresented = true
}
.padding(.top, 12)
.accessibilityIdentifier("ScanPrompt")
}
}
}
.navigationBarHidden(false)
Expand All @@ -54,6 +69,28 @@ struct ScannerSheet: View {
sheets: sheets
)
}
.sheet(isPresented: $isManualEntryPresented) {
ScannerManualEntryPrompt(
text: $manualEntry,
onSubmit: {
Task {
await handleManualEntrySubmit()
}
},
onCancel: {
isManualEntryPresented = false
}
)
.presentationDetents([.fraction(0.35)])
.presentationDragIndicator(.visible)
}
}
}

private func handleManualEntrySubmit() async {
await scanner.handleManualEntry(manualEntry, context: .main) {
isManualEntryPresented = false
manualEntry = ""
}
}
}
Loading