diff --git a/iosApp/HoneyDueTests/SnapshotGalleryTests.swift b/iosApp/HoneyDueTests/SnapshotGalleryTests.swift new file mode 100644 index 0000000..4f006be --- /dev/null +++ b/iosApp/HoneyDueTests/SnapshotGalleryTests.swift @@ -0,0 +1,339 @@ +// +// SnapshotGalleryTests.swift +// HoneyDueTests +// +// P3 — iOS parity gallery. Records baseline PNGs for primary SwiftUI screens +// across {empty-state} × {light, dark}. Complements the Android Roborazzi +// gallery (P2); both platforms consume the same Kotlin FixtureDataManager +// fixtures (P1), so any layout divergence between Android + iOS renders of +// the same screen is a real parity bug — not a test-data mismatch. +// +// Current state coverage +// ---------------------- +// * Empty (signed-in user with no residences / tasks / docs / contractors) +// is captured for every screen below via the default +// `DataManagerObservable.shared`, which has no data loaded when tests run +// because no login has occurred in the test host. +// * Populated state is BLOCKED on a follow-up ViewModel-injection refactor: +// current SwiftUI screens instantiate their ViewModels via +// `@StateObject private var viewModel = FooViewModel()`, and those +// ViewModels read directly from `DataManagerObservable.shared` rather +// than an injected `IDataManager`. Swapping the singleton is unsafe in +// parallel tests. Follow-up PR: add an optional `dataManager:` init param +// to each `*ViewModel.swift` and thread it from here via +// `.environment(\.dataManager, ...)`. +// +// Recording goldens +// ----------------- +// Set `isRecording = true` in `setUp()`, run the target, then flip back to +// `false` before committing. CI fails the build if a screen diverges from +// its golden by more than the precision threshold. +// + +@preconcurrency import SnapshotTesting +import SwiftUI +import XCTest +import ComposeApp +@testable import honeyDue + +@MainActor +final class SnapshotGalleryTests: XCTestCase { + + // Flip to true locally, run the scheme, revert, commit. + private static let recordMode: SnapshotTestingConfiguration.Record = .missing + + override func invokeTest() { + withSnapshotTesting(record: Self.recordMode) { + super.invokeTest() + } + } + + // MARK: - Helpers + + /// Snapshot a SwiftUI view in both light + dark modes under a stable + /// iPhone 13 layout. The screen is wrapped in a `NavigationStack` so that + /// any `.navigationTitle`/`.toolbar` chrome the view declares is rendered + /// identically to how it ships to users. + // Most HoneyDue screens animate on appear (OrganicBlobShape gradients, + // subtle pulses, TextField focus rings). A tiny amount of pixel drift + // between runs is expected; the goal of parity snapshots is to catch + // *structural* regressions, not single-pixel anti-alias differences. + // These thresholds were tuned so that a second run against goldens + // recorded on the first run passes green. + private static let pixelPrecision: Float = 0.97 + private static let perceptualPrecision: Float = 0.95 + + private func snap( + _ name: String, + file: StaticString = #filePath, + testName: String = #function, + line: UInt = #line, + @ViewBuilder content: () -> V + ) { + let view = content() + .environmentObject(ThemeManager.shared) + .environment(\.dataManager, DataManagerObservable.shared) + + assertSnapshot( + of: view.environment(\.colorScheme, .light), + as: .image( + precision: Self.pixelPrecision, + perceptualPrecision: Self.perceptualPrecision, + layout: .device(config: .iPhone13), + traits: .init(userInterfaceStyle: .light) + ), + named: "\(name)_light", + file: file, + testName: testName, + line: line + ) + assertSnapshot( + of: view.environment(\.colorScheme, .dark), + as: .image( + precision: Self.pixelPrecision, + perceptualPrecision: Self.perceptualPrecision, + layout: .device(config: .iPhone13), + traits: .init(userInterfaceStyle: .dark) + ), + named: "\(name)_dark", + file: file, + testName: testName, + line: line + ) + } + + // MARK: - Auth flow + + func test_login_empty() { + snap("login_empty") { + LoginView(resetToken: .constant(nil), onLoginSuccess: nil) + } + } + + func test_register_empty() { + snap("register_empty") { + RegisterView(isPresented: .constant(true), onVerified: nil) + } + } + + func test_verify_email_empty() { + snap("verify_email_empty") { + VerifyEmailView(onVerifySuccess: {}, onLogout: {}) + } + } + + func test_forgot_password_empty() { + let vm = PasswordResetViewModel() + snap("forgot_password_empty") { + NavigationStack { ForgotPasswordView(viewModel: vm) } + } + } + + func test_verify_reset_code_empty() { + let vm = PasswordResetViewModel() + vm.email = "user@example.com" + vm.currentStep = .verifyCode + snap("verify_reset_code_empty") { + NavigationStack { VerifyResetCodeView(viewModel: vm) } + } + } + + func test_reset_password_empty() { + let vm = PasswordResetViewModel() + vm.currentStep = .resetPassword + snap("reset_password_empty") { + NavigationStack { ResetPasswordView(viewModel: vm, onSuccess: {}) } + } + } + + // MARK: - Onboarding + + func test_onboarding_welcome_empty() { + snap("onboarding_welcome_empty") { + OnboardingWelcomeView(onStartFresh: {}, onJoinExisting: {}, onLogin: {}) + } + } + + func test_onboarding_value_props_empty() { + snap("onboarding_value_props_empty") { + OnboardingValuePropsView(onContinue: {}, onSkip: {}, onBack: {}) + } + } + + func test_onboarding_create_account_empty() { + snap("onboarding_create_account_empty") { + OnboardingCreateAccountView(onAccountCreated: { _ in }, onBack: {}) + } + } + + func test_onboarding_verify_email_empty() { + snap("onboarding_verify_email_empty") { + OnboardingVerifyEmailView(onVerified: {}, onLogout: {}) + } + } + + func test_onboarding_name_residence_empty() { + snap("onboarding_name_residence_empty") { + StatefulPreviewWrapper("") { binding in + OnboardingNameResidenceView( + residenceName: binding, + onContinue: {}, + onBack: {} + ) + } + } + } + + func test_onboarding_join_residence_empty() { + snap("onboarding_join_residence_empty") { + OnboardingJoinResidenceView(onJoined: {}, onSkip: {}) + } + } + + func test_onboarding_subscription_empty() { + snap("onboarding_subscription_empty") { + OnboardingSubscriptionView(onSubscribe: {}, onSkip: {}) + } + } + + func test_onboarding_first_task_empty() { + snap("onboarding_first_task_empty") { + OnboardingFirstTaskView( + residenceName: "My House", + onTaskAdded: {}, + onSkip: {} + ) + } + } + + // MARK: - Residence + + func test_residences_list_empty() { + snap("residences_list_empty") { + NavigationStack { ResidencesListView() } + } + } + + func test_add_residence_empty() { + snap("add_residence_empty") { + AddResidenceView(isPresented: .constant(true), onResidenceCreated: nil) + } + } + + func test_join_residence_empty() { + snap("join_residence_empty") { + JoinResidenceView(onJoined: {}) + } + } + + // MARK: - Tasks + + func test_all_tasks_empty() { + snap("all_tasks_empty") { + NavigationStack { AllTasksView() } + } + } + + func test_add_task_empty() { + snap("add_task_empty") { + AddTaskView(residenceId: 1, isPresented: .constant(true)) + } + } + + func test_add_task_with_residence_empty() { + snap("add_task_with_residence_empty") { + AddTaskWithResidenceView(isPresented: .constant(true), residences: []) + } + } + + func test_task_suggestions_empty() { + snap("task_suggestions_empty") { + TaskSuggestionsView( + suggestions: [], + onSelect: { _ in } + ) + } + } + + func test_task_templates_browser_empty() { + snap("task_templates_browser_empty") { + NavigationStack { TaskTemplatesBrowserView(onSelect: { _ in }) } + } + } + + // MARK: - Contractor + + func test_contractors_list_empty() { + snap("contractors_list_empty") { + NavigationStack { ContractorsListView() } + } + } + + // MARK: - Documents + + func test_documents_warranties_empty() { + snap("documents_warranties_empty") { + NavigationStack { DocumentsWarrantiesView(residenceId: nil) } + } + } + + // MARK: - Profile + + func test_profile_tab_empty() { + snap("profile_tab_empty") { + NavigationStack { ProfileTabView() } + } + } + + func test_profile_edit_empty() { + snap("profile_edit_empty") { + NavigationStack { ProfileView() } + } + } + + func test_notification_preferences_empty() { + snap("notification_preferences_empty") { + NavigationStack { NotificationPreferencesView() } + } + } + + func test_theme_selection_empty() { + snap("theme_selection_empty") { + NavigationStack { ThemeSelectionView() } + } + } + + // MARK: - Subscription + + func test_feature_comparison_empty() { + snap("feature_comparison_empty") { + FeatureComparisonView(isPresented: .constant(true)) + } + } + + // NOTE: UpgradeFeatureView is intentionally excluded from the parity + // gallery. It reads `SubscriptionCacheWrapper.shared` and + // `StoreKitManager.shared` on appear, both of which populate + // asynchronously in a way that isn't deterministic inside a snapshot + // test. Follow-up PR should add a fixture-friendly init override + // mirroring the `dataManager:` pattern. +} + +// MARK: - StatefulPreviewWrapper + +/// Lets us hand a view a `@Binding` backed by a local `@State` so that +/// views which mutate bindings (e.g. `OnboardingNameResidenceView`) render +/// correctly inside a snapshot test — which has no surrounding state host. +private struct StatefulPreviewWrapper: View { + @State private var value: Value + let content: (Binding) -> Content + + init(_ initial: Value, @ViewBuilder content: @escaping (Binding) -> Content) { + _value = State(initialValue: initial) + self.content = content + } + + var body: some View { + content($value) + } +} diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_residence_empty.add_residence_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_residence_empty.add_residence_empty_dark.png new file mode 100644 index 0000000..fc09435 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_residence_empty.add_residence_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_residence_empty.add_residence_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_residence_empty.add_residence_empty_light.png new file mode 100644 index 0000000..5f00ec2 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_residence_empty.add_residence_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_empty.add_task_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_empty.add_task_empty_dark.png new file mode 100644 index 0000000..0eae98d Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_empty.add_task_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_empty.add_task_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_empty.add_task_empty_light.png new file mode 100644 index 0000000..f444d14 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_empty.add_task_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_with_residence_empty.add_task_with_residence_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_with_residence_empty.add_task_with_residence_empty_dark.png new file mode 100644 index 0000000..2a54c3e Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_with_residence_empty.add_task_with_residence_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_with_residence_empty.add_task_with_residence_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_with_residence_empty.add_task_with_residence_empty_light.png new file mode 100644 index 0000000..d0732bc Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_add_task_with_residence_empty.add_task_with_residence_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_all_tasks_empty.all_tasks_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_all_tasks_empty.all_tasks_empty_dark.png new file mode 100644 index 0000000..5cba41f Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_all_tasks_empty.all_tasks_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_all_tasks_empty.all_tasks_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_all_tasks_empty.all_tasks_empty_light.png new file mode 100644 index 0000000..1a74219 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_all_tasks_empty.all_tasks_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_contractors_list_empty.contractors_list_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_contractors_list_empty.contractors_list_empty_dark.png new file mode 100644 index 0000000..8c5078d Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_contractors_list_empty.contractors_list_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_contractors_list_empty.contractors_list_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_contractors_list_empty.contractors_list_empty_light.png new file mode 100644 index 0000000..586dff5 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_contractors_list_empty.contractors_list_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_documents_warranties_empty.documents_warranties_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_documents_warranties_empty.documents_warranties_empty_dark.png new file mode 100644 index 0000000..16b0e71 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_documents_warranties_empty.documents_warranties_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_documents_warranties_empty.documents_warranties_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_documents_warranties_empty.documents_warranties_empty_light.png new file mode 100644 index 0000000..2a94243 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_documents_warranties_empty.documents_warranties_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_feature_comparison_empty.feature_comparison_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_feature_comparison_empty.feature_comparison_empty_dark.png new file mode 100644 index 0000000..9fd0cbd Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_feature_comparison_empty.feature_comparison_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_feature_comparison_empty.feature_comparison_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_feature_comparison_empty.feature_comparison_empty_light.png new file mode 100644 index 0000000..1b2da73 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_feature_comparison_empty.feature_comparison_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_forgot_password_empty.forgot_password_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_forgot_password_empty.forgot_password_empty_dark.png new file mode 100644 index 0000000..35373d4 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_forgot_password_empty.forgot_password_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_forgot_password_empty.forgot_password_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_forgot_password_empty.forgot_password_empty_light.png new file mode 100644 index 0000000..f34c1e4 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_forgot_password_empty.forgot_password_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_join_residence_empty.join_residence_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_join_residence_empty.join_residence_empty_dark.png new file mode 100644 index 0000000..0cb3bd5 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_join_residence_empty.join_residence_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_join_residence_empty.join_residence_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_join_residence_empty.join_residence_empty_light.png new file mode 100644 index 0000000..fae8b76 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_join_residence_empty.join_residence_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_login_empty.login_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_login_empty.login_empty_dark.png new file mode 100644 index 0000000..720f28e Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_login_empty.login_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_login_empty.login_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_login_empty.login_empty_light.png new file mode 100644 index 0000000..0fea715 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_login_empty.login_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_notification_preferences_empty.notification_preferences_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_notification_preferences_empty.notification_preferences_empty_dark.png new file mode 100644 index 0000000..6a236d0 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_notification_preferences_empty.notification_preferences_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_notification_preferences_empty.notification_preferences_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_notification_preferences_empty.notification_preferences_empty_light.png new file mode 100644 index 0000000..c870ff2 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_notification_preferences_empty.notification_preferences_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_create_account_empty.onboarding_create_account_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_create_account_empty.onboarding_create_account_empty_dark.png new file mode 100644 index 0000000..3f3bac6 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_create_account_empty.onboarding_create_account_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_create_account_empty.onboarding_create_account_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_create_account_empty.onboarding_create_account_empty_light.png new file mode 100644 index 0000000..35b8d5f Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_create_account_empty.onboarding_create_account_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_first_task_empty.onboarding_first_task_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_first_task_empty.onboarding_first_task_empty_dark.png new file mode 100644 index 0000000..bdc45fa Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_first_task_empty.onboarding_first_task_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_first_task_empty.onboarding_first_task_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_first_task_empty.onboarding_first_task_empty_light.png new file mode 100644 index 0000000..b0f33e6 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_first_task_empty.onboarding_first_task_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_join_residence_empty.onboarding_join_residence_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_join_residence_empty.onboarding_join_residence_empty_dark.png new file mode 100644 index 0000000..0abfbaf Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_join_residence_empty.onboarding_join_residence_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_join_residence_empty.onboarding_join_residence_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_join_residence_empty.onboarding_join_residence_empty_light.png new file mode 100644 index 0000000..0a0f07b Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_join_residence_empty.onboarding_join_residence_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_name_residence_empty.onboarding_name_residence_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_name_residence_empty.onboarding_name_residence_empty_dark.png new file mode 100644 index 0000000..c7f93c7 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_name_residence_empty.onboarding_name_residence_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_name_residence_empty.onboarding_name_residence_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_name_residence_empty.onboarding_name_residence_empty_light.png new file mode 100644 index 0000000..b7395ac Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_name_residence_empty.onboarding_name_residence_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_subscription_empty.onboarding_subscription_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_subscription_empty.onboarding_subscription_empty_dark.png new file mode 100644 index 0000000..8259ae9 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_subscription_empty.onboarding_subscription_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_subscription_empty.onboarding_subscription_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_subscription_empty.onboarding_subscription_empty_light.png new file mode 100644 index 0000000..f1ef01b Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_subscription_empty.onboarding_subscription_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_value_props_empty.onboarding_value_props_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_value_props_empty.onboarding_value_props_empty_dark.png new file mode 100644 index 0000000..5296830 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_value_props_empty.onboarding_value_props_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_value_props_empty.onboarding_value_props_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_value_props_empty.onboarding_value_props_empty_light.png new file mode 100644 index 0000000..ff0cec6 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_value_props_empty.onboarding_value_props_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_verify_email_empty.onboarding_verify_email_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_verify_email_empty.onboarding_verify_email_empty_dark.png new file mode 100644 index 0000000..9b721c3 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_verify_email_empty.onboarding_verify_email_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_verify_email_empty.onboarding_verify_email_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_verify_email_empty.onboarding_verify_email_empty_light.png new file mode 100644 index 0000000..a29c93c Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_verify_email_empty.onboarding_verify_email_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_welcome_empty.onboarding_welcome_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_welcome_empty.onboarding_welcome_empty_dark.png new file mode 100644 index 0000000..46b5524 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_welcome_empty.onboarding_welcome_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_welcome_empty.onboarding_welcome_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_welcome_empty.onboarding_welcome_empty_light.png new file mode 100644 index 0000000..8cab6e7 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_onboarding_welcome_empty.onboarding_welcome_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_edit_empty.profile_edit_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_edit_empty.profile_edit_empty_dark.png new file mode 100644 index 0000000..4a549c8 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_edit_empty.profile_edit_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_edit_empty.profile_edit_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_edit_empty.profile_edit_empty_light.png new file mode 100644 index 0000000..e2286e5 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_edit_empty.profile_edit_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_tab_empty.profile_tab_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_tab_empty.profile_tab_empty_dark.png new file mode 100644 index 0000000..bdcc338 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_tab_empty.profile_tab_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_tab_empty.profile_tab_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_tab_empty.profile_tab_empty_light.png new file mode 100644 index 0000000..209d868 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_profile_tab_empty.profile_tab_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_register_empty.register_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_register_empty.register_empty_dark.png new file mode 100644 index 0000000..5179e23 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_register_empty.register_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_register_empty.register_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_register_empty.register_empty_light.png new file mode 100644 index 0000000..0559956 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_register_empty.register_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_reset_password_empty.reset_password_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_reset_password_empty.reset_password_empty_dark.png new file mode 100644 index 0000000..9e25b6a Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_reset_password_empty.reset_password_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_reset_password_empty.reset_password_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_reset_password_empty.reset_password_empty_light.png new file mode 100644 index 0000000..0e5e891 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_reset_password_empty.reset_password_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_residences_list_empty.residences_list_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_residences_list_empty.residences_list_empty_dark.png new file mode 100644 index 0000000..5cba41f Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_residences_list_empty.residences_list_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_residences_list_empty.residences_list_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_residences_list_empty.residences_list_empty_light.png new file mode 100644 index 0000000..1a74219 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_residences_list_empty.residences_list_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_suggestions_empty.task_suggestions_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_suggestions_empty.task_suggestions_empty_dark.png new file mode 100644 index 0000000..646c061 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_suggestions_empty.task_suggestions_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_suggestions_empty.task_suggestions_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_suggestions_empty.task_suggestions_empty_light.png new file mode 100644 index 0000000..c266f44 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_suggestions_empty.task_suggestions_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_templates_browser_empty.task_templates_browser_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_templates_browser_empty.task_templates_browser_empty_dark.png new file mode 100644 index 0000000..1f7f821 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_templates_browser_empty.task_templates_browser_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_templates_browser_empty.task_templates_browser_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_templates_browser_empty.task_templates_browser_empty_light.png new file mode 100644 index 0000000..8f86ee3 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_task_templates_browser_empty.task_templates_browser_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_theme_selection_empty.theme_selection_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_theme_selection_empty.theme_selection_empty_dark.png new file mode 100644 index 0000000..2a91c0b Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_theme_selection_empty.theme_selection_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_theme_selection_empty.theme_selection_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_theme_selection_empty.theme_selection_empty_light.png new file mode 100644 index 0000000..a30255c Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_theme_selection_empty.theme_selection_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_email_empty.verify_email_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_email_empty.verify_email_empty_dark.png new file mode 100644 index 0000000..59627c8 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_email_empty.verify_email_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_email_empty.verify_email_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_email_empty.verify_email_empty_light.png new file mode 100644 index 0000000..addd861 Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_email_empty.verify_email_empty_light.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_reset_code_empty.verify_reset_code_empty_dark.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_reset_code_empty.verify_reset_code_empty_dark.png new file mode 100644 index 0000000..7c9ae6a Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_reset_code_empty.verify_reset_code_empty_dark.png differ diff --git a/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_reset_code_empty.verify_reset_code_empty_light.png b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_reset_code_empty.verify_reset_code_empty_light.png new file mode 100644 index 0000000..8f1f21a Binary files /dev/null and b/iosApp/HoneyDueTests/__Snapshots__/SnapshotGalleryTests/test_verify_reset_code_empty.verify_reset_code_empty_light.png differ diff --git a/iosApp/honeyDue.xcodeproj/project.pbxproj b/iosApp/honeyDue.xcodeproj/project.pbxproj index 9e58777..51d0397 100644 --- a/iosApp/honeyDue.xcodeproj/project.pbxproj +++ b/iosApp/honeyDue.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 1C81F2822EE41BB6000739EA /* QuickLookThumbnailing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C81F2812EE41BB6000739EA /* QuickLookThumbnailing.framework */; }; 1C81F2892EE41BB6000739EA /* HoneyDueQLThumbnail.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 1C81F2802EE41BB6000739EA /* HoneyDueQLThumbnail.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 1C81F3902EE69AF1000739EA /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = 1C81F38F2EE69AF1000739EA /* PostHog */; }; + 36A43DA6D19BA51568EC55A5 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 6424E7E39866AD706041F321 /* SnapshotTesting */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -201,6 +202,8 @@ }; 7A237E53D5D71D9D6A361E29 /* Configuration */ = { isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + ); path = Configuration; sourceTree = ""; }; @@ -230,6 +233,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 36A43DA6D19BA51568EC55A5 /* SnapshotTesting in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -337,8 +341,6 @@ 1C0789432EBC218B00392B46 /* HoneyDue */, ); name = HoneyDueExtension; - packageProductDependencies = ( - ); productName = HoneyDueExtension; productReference = 1C07893D2EBC218B00392B46 /* HoneyDueExtension.appex */; productType = "com.apple.product-type.app-extension"; @@ -361,6 +363,7 @@ ); name = HoneyDueTests; packageProductDependencies = ( + 6424E7E39866AD706041F321 /* SnapshotTesting */, ); productName = HoneyDueTests; productReference = 1C685CD22EC5539000A9669B /* HoneyDueTests.xctest */; @@ -382,8 +385,6 @@ 1C81F26C2EE416EE000739EA /* HoneyDueQLPreview */, ); name = HoneyDueQLPreview; - packageProductDependencies = ( - ); productName = HoneyDueQLPreview; productReference = 1C81F2692EE416EE000739EA /* HoneyDueQLPreview.appex */; productType = "com.apple.product-type.app-extension"; @@ -404,8 +405,6 @@ 1C81F2832EE41BB6000739EA /* HoneyDueQLThumbnail */, ); name = HoneyDueQLThumbnail; - packageProductDependencies = ( - ); productName = HoneyDueQLThumbnail; productReference = 1C81F2802EE41BB6000739EA /* HoneyDueQLThumbnail.appex */; productType = "com.apple.product-type.app-extension"; @@ -427,8 +426,6 @@ 1CBF1BEE2ECD9768001BF56C /* HoneyDueUITests */, ); name = HoneyDueUITests; - packageProductDependencies = ( - ); productName = HoneyDueUITests; productReference = 1CBF1BED2ECD9768001BF56C /* HoneyDueUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -504,6 +501,7 @@ minimizedProjectReferenceProxies = 1; packageReferences = ( 1C81F38E2EE69698000739EA /* XCRemoteSwiftPackageReference "posthog-ios" */, + 15EBA3121E0FD8442B65FC71 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */, ); preferredProjectObjectVersion = 77; productRefGroup = FA6022B7B844191C54E57EB4 /* Products */; @@ -1224,6 +1222,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 15EBA3121E0FD8442B65FC71 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.17.0; + }; + }; 1C81F38E2EE69698000739EA /* XCRemoteSwiftPackageReference "posthog-ios" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/PostHog/posthog-ios.git"; @@ -1240,6 +1246,11 @@ package = 1C81F38E2EE69698000739EA /* XCRemoteSwiftPackageReference "posthog-ios" */; productName = PostHog; }; + 6424E7E39866AD706041F321 /* SnapshotTesting */ = { + isa = XCSwiftPackageProductDependency; + package = 15EBA3121E0FD8442B65FC71 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; + productName = SnapshotTesting; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 6A3E1D84F9F1A2FD92A75A6C /* Project object */; diff --git a/iosApp/honeyDue.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/iosApp/honeyDue.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index aca80d8..18749f9 100644 --- a/iosApp/honeyDue.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/iosApp/honeyDue.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "47cbe4ef2adc7155b834c1fb5ae451e260f9ef6ba19f0658c4fcafd3565fad48", + "originHash" : "8d2dc312a50c3ca2edce0566ec936acffb1ad4994986cda0c1f773163efa59de", "pins" : [ { "identity" : "posthog-ios", @@ -9,6 +9,42 @@ "revision" : "fac9fc77380d2a38c3389f3cf4505a534921ee41", "version" : "3.35.1" } + }, + { + "identity" : "swift-custom-dump", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-custom-dump", + "state" : { + "revision" : "06c57924455064182d6b217f06ebc05d00cb2990", + "version" : "1.5.0" + } + }, + { + "identity" : "swift-snapshot-testing", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-snapshot-testing", + "state" : { + "revision" : "ad5e3190cc63dc288f28546f9c6827efc1e9d495", + "version" : "1.19.2" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-syntax", + "state" : { + "revision" : "2b59c0c741e9184ab057fd22950b491076d42e91", + "version" : "603.0.0" + } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "dfd70507def84cb5fb821278448a262c6ff2bbad", + "version" : "1.9.0" + } } ], "version" : 3 diff --git a/scripts/add_snapshot_testing.rb b/scripts/add_snapshot_testing.rb new file mode 100644 index 0000000..eafdff6 --- /dev/null +++ b/scripts/add_snapshot_testing.rb @@ -0,0 +1,70 @@ +#!/usr/bin/env ruby +# Adds swift-snapshot-testing SPM dependency to the HoneyDueTests target. +# Idempotent — safe to run repeatedly. +# +# Usage: +# ruby scripts/add_snapshot_testing.rb +# +# Requires: +# gem install xcodeproj +# +# Repo-root-relative; must be run from repo root or via absolute path. + +require 'xcodeproj' + +PROJECT_PATH = File.expand_path('../iosApp/honeyDue.xcodeproj', __dir__) +PACKAGE_URL = 'https://github.com/pointfreeco/swift-snapshot-testing' +PACKAGE_VERSION = '1.17.0' +PRODUCT = 'SnapshotTesting' +TARGET_NAME = 'HoneyDueTests' + +project = Xcodeproj::Project.open(PROJECT_PATH) +target = project.targets.find { |t| t.name == TARGET_NAME } +abort("Target #{TARGET_NAME} not found") unless target + +# 1. XCRemoteSwiftPackageReference — create if missing +pkg_ref = project.root_object.package_references.find do |ref| + ref.respond_to?(:repositoryURL) && ref.repositoryURL == PACKAGE_URL +end + +if pkg_ref.nil? + pkg_ref = project.new(Xcodeproj::Project::Object::XCRemoteSwiftPackageReference) + pkg_ref.repositoryURL = PACKAGE_URL + pkg_ref.requirement = { 'kind' => 'upToNextMajorVersion', 'minimumVersion' => PACKAGE_VERSION } + project.root_object.package_references << pkg_ref + puts "Added XCRemoteSwiftPackageReference: #{PACKAGE_URL}" +else + pkg_ref.requirement = { 'kind' => 'upToNextMajorVersion', 'minimumVersion' => PACKAGE_VERSION } + puts "XCRemoteSwiftPackageReference already exists: #{PACKAGE_URL}" +end + +# 2. XCSwiftPackageProductDependency — SnapshotTesting product tied to package ref +prod_dep = target.package_product_dependencies.find { |d| d.product_name == PRODUCT } + +if prod_dep.nil? + prod_dep = project.new(Xcodeproj::Project::Object::XCSwiftPackageProductDependency) + prod_dep.package = pkg_ref + prod_dep.product_name = PRODUCT + target.package_product_dependencies << prod_dep + puts "Added XCSwiftPackageProductDependency: #{PRODUCT} -> #{TARGET_NAME}" +else + puts "XCSwiftPackageProductDependency #{PRODUCT} already linked to #{TARGET_NAME}" +end + +# 3. Frameworks build phase — add build file referencing the product dep +frameworks_phase = target.frameworks_build_phase +already_linked = frameworks_phase.files.any? do |bf| + bf.file_ref.nil? && bf.product_ref == prod_dep +end + +unless already_linked + build_file = project.new(Xcodeproj::Project::Object::PBXBuildFile) + build_file.product_ref = prod_dep + frameworks_phase.files << build_file + puts "Added #{PRODUCT} to Frameworks build phase of #{TARGET_NAME}" +else + puts "#{PRODUCT} already in Frameworks build phase" +end + +project.save +puts "Saved project."