Add snapshot tests and CI
Seto Elkahfi committed
May 15, 2026 at 06:56 UTC
4b2a38242b9158bc5041f23a07e6e99432d9f774
9 files changed
+361
-2
.github/workflows/ci.yml
new
+35
@@ -0,0 +1,35 @@
1
+name: CI
2
+
3
+on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+ - feature/**
9
+
10
+jobs:
11
+ snapshot-tests:
12
+ name: Snapshot tests
13
+ runs-on: macos-26
14
+
15
+ steps:
16
+ - name: Checkout
17
+ uses: actions/checkout@v6
18
+
19
+ - name: Install XcodeGen
20
+ run: brew install xcodegen
21
+
22
+ - name: Generate project
23
+ run: xcodegen generate
24
+
25
+ - name: Resolve Swift packages
26
+ run: xcodebuild -project Klepon.xcodeproj -scheme Klepon -resolvePackageDependencies
27
+
28
+ - name: Run snapshot tests
29
+ run: |
30
+ xcodebuild test \
31
+ -project Klepon.xcodeproj \
32
+ -scheme Klepon \
33
+ -destination 'platform=iOS Simulator,OS=26.0.1,name=iPhone 17' \
34
+ -only-testing:KleponSnapshotTests \
35
+ CODE_SIGNING_ALLOWED=NO
Klepon.xcodeproj/project.pbxproj
+129
@@ -48,12 +48,21 @@
48
D99AAE1CDE51139840A52607 /* KleponMetadataRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7E1C50BFBE2EF5F37941590 /* KleponMetadataRow.swift */; };
49
DA915BA8B2F732E7D62CF936 /* EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */; };
50
E45F257E3D35DC565B21B299 /* KleponColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C675ABBBA25BBA25A8DE29BE /* KleponColor.swift */; };
51
+ E599CCDB1FE5331C4A1EB6C6 /* KleponSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 759E92BBAF958F5882F17C37 /* KleponSnapshotTests.swift */; };
52
+ EE88AEC7059BB2639687FECF /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 35214C3FF433B08C1C06C3F7 /* SnapshotTesting */; };
53
F1431179B54CEB23FFFCB2AE /* KleponApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEDE2A1E73EB15970A17A894 /* KleponApp.swift */; };
54
FA423A76BE098A9911044246 /* AskSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC6E7DC56DD8E1459EFC892 /* AskSheetView.swift */; };
55
FD0E1BA888E3CE73875D58FF /* RecentSearchStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643D52BCEDF66CC8FE8A1234 /* RecentSearchStore.swift */; };
56
/* End PBXBuildFile section */
57
58
/* Begin PBXContainerItemProxy section */
59
+ C24CD5A7B8399776539D1FF4 /* PBXContainerItemProxy */ = {
60
+ isa = PBXContainerItemProxy;
61
+ containerPortal = 05A5707BDA883282DEB132FF /* Project object */;
62
+ proxyType = 1;
63
+ remoteGlobalIDString = 2ADB11F6C1D51B9F9A9DB15F;
64
+ remoteInfo = Klepon;
65
+ };
66
D55C73775065842DC4A51797 /* PBXContainerItemProxy */ = {
67
isa = PBXContainerItemProxy;
68
containerPortal = 05A5707BDA883282DEB132FF /* Project object */;
@@ -99,12 +108,14 @@
108
6B67BCC5A459288FB240C6E7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
109
6EFBF98118F066D3C7FA14B2 /* KleponWatchApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponWatchApp.swift; sourceTree = "<group>"; };
110
7541983FF7CE190C0663294D /* GuideDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuideDetailView.swift; sourceTree = "<group>"; };
111
+ 759E92BBAF958F5882F17C37 /* KleponSnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponSnapshotTests.swift; sourceTree = "<group>"; };
112
7F2850226B4B05FF758C1F93 /* GuideArtworkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuideArtworkView.swift; sourceTree = "<group>"; };
113
85E7B5E3D9A1906C2FED3032 /* EmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyStateView.swift; sourceTree = "<group>"; };
114
868C58098969278A542893F3 /* KleponCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponCard.swift; sourceTree = "<group>"; };
115
98AA2E425D5454602F78D628 /* SavedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavedView.swift; sourceTree = "<group>"; };
116
9E76510CC840CE068B0FC381 /* Klepon Watch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Klepon Watch.app"; sourceTree = BUILT_PRODUCTS_DIR; };
117
A4400AB0AB8D245325A00BA3 /* Klepon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Klepon.entitlements; sourceTree = "<group>"; };
118
+ A48AC0E39277DEFCE5D103CC /* KleponSnapshotTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = KleponSnapshotTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
119
A7E1C50BFBE2EF5F37941590 /* KleponMetadataRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KleponMetadataRow.swift; sourceTree = "<group>"; };
120
AF79D8DD27B9CA485140C934 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
121
B02B0EA4B8BA09604D62A62B /* AnswerCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnswerCard.swift; sourceTree = "<group>"; };
@@ -125,6 +136,14 @@
136
/* End PBXFileReference section */
137
138
/* Begin PBXFrameworksBuildPhase section */
139
+ B161A429683CBAD2A984A5AE /* Frameworks */ = {
140
+ isa = PBXFrameworksBuildPhase;
141
+ buildActionMask = 2147483647;
142
+ files = (
143
+ EE88AEC7059BB2639687FECF /* SnapshotTesting in Frameworks */,
144
+ );
145
+ runOnlyForDeploymentPostprocessing = 0;
146
+ };
147
F72797E506E8FA89264A5C68 /* Frameworks */ = {
148
isa = PBXFrameworksBuildPhase;
149
buildActionMask = 2147483647;
@@ -157,6 +176,7 @@
176
children = (
177
9E76510CC840CE068B0FC381 /* Klepon Watch.app */,
178
5DE91827A635C0B0B72690EC /* Klepon.app */,
179
+ A48AC0E39277DEFCE5D103CC /* KleponSnapshotTests.xctest */,
180
);
181
name = Products;
182
sourceTree = "<group>";
@@ -230,6 +250,14 @@
250
path = App;
251
sourceTree = "<group>";
252
};
253
+ 825A58FCE091C3FE902D3131 /* KleponSnapshotTests */ = {
254
+ isa = PBXGroup;
255
+ children = (
256
+ 759E92BBAF958F5882F17C37 /* KleponSnapshotTests.swift */,
257
+ );
258
+ path = KleponSnapshotTests;
259
+ sourceTree = "<group>";
260
+ };
261
82A3750644C21DE5F301405D /* AI */ = {
262
isa = PBXGroup;
263
children = (
@@ -316,6 +344,7 @@
344
children = (
345
038E8FA398B5CB76373031FD /* Configs */,
346
EA4DFA44FE8BB01979ADB187 /* Klepon */,
347
+ 825A58FCE091C3FE902D3131 /* KleponSnapshotTests */,
348
472BF5D47BEE4AF1EC80B645 /* KleponWatch */,
349
3F9369D339C14126AB44D720 /* Products */,
350
);
@@ -383,6 +412,26 @@
412
productReference = 9E76510CC840CE068B0FC381 /* Klepon Watch.app */;
413
productType = "com.apple.product-type.application";
414
};
415
+ F10E9562BA0BE60A7E000DB0 /* KleponSnapshotTests */ = {
416
+ isa = PBXNativeTarget;
417
+ buildConfigurationList = 116221FC6D50F33334387509 /* Build configuration list for PBXNativeTarget "KleponSnapshotTests" */;
418
+ buildPhases = (
419
+ C2B1B8ADEE7B8E2628B90D1F /* Sources */,
420
+ B161A429683CBAD2A984A5AE /* Frameworks */,
421
+ );
422
+ buildRules = (
423
+ );
424
+ dependencies = (
425
+ C8D72D1B1BE79610DB905424 /* PBXTargetDependency */,
426
+ );
427
+ name = KleponSnapshotTests;
428
+ packageProductDependencies = (
429
+ 35214C3FF433B08C1C06C3F7 /* SnapshotTesting */,
430
+ );
431
+ productName = KleponSnapshotTests;
432
+ productReference = A48AC0E39277DEFCE5D103CC /* KleponSnapshotTests.xctest */;
433
+ productType = "com.apple.product-type.bundle.unit-test";
434
+ };
435
/* End PBXNativeTarget section */
436
437
/* Begin PBXProject section */
@@ -398,6 +447,9 @@
447
E8CEBF52617721AEE450A7CF = {
448
ProvisioningStyle = Automatic;
449
};
450
+ F10E9562BA0BE60A7E000DB0 = {
451
+ ProvisioningStyle = Automatic;
452
+ };
453
};
454
};
455
buildConfigurationList = 8911E6C6F25C3A4F99870749 /* Build configuration list for PBXProject "Klepon" */;
@@ -411,6 +463,7 @@
463
minimizedProjectReferenceProxies = 1;
464
packageReferences = (
465
AD8C734FB461604D5793769C /* XCRemoteSwiftPackageReference "onde-swift" */,
466
+ 85B622113A5DC5A1BD2D123B /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */,
467
);
468
preferredProjectObjectVersion = 77;
469
productRefGroup = 3F9369D339C14126AB44D720 /* Products */;
@@ -419,6 +472,7 @@
472
targets = (
473
2ADB11F6C1D51B9F9A9DB15F /* Klepon */,
474
E8CEBF52617721AEE450A7CF /* Klepon Watch */,
475
+ F10E9562BA0BE60A7E000DB0 /* KleponSnapshotTests */,
476
);
477
};
478
/* End PBXProject section */
@@ -540,6 +594,14 @@
594
);
595
runOnlyForDeploymentPostprocessing = 0;
596
};
597
+ C2B1B8ADEE7B8E2628B90D1F /* Sources */ = {
598
+ isa = PBXSourcesBuildPhase;
599
+ buildActionMask = 2147483647;
600
+ files = (
601
+ E599CCDB1FE5331C4A1EB6C6 /* KleponSnapshotTests.swift in Sources */,
602
+ );
603
+ runOnlyForDeploymentPostprocessing = 0;
604
+ };
605
/* End PBXSourcesBuildPhase section */
606
607
/* Begin PBXTargetDependency section */
@@ -548,9 +610,54 @@
610
target = E8CEBF52617721AEE450A7CF /* Klepon Watch */;
611
targetProxy = D55C73775065842DC4A51797 /* PBXContainerItemProxy */;
612
};
613
+ C8D72D1B1BE79610DB905424 /* PBXTargetDependency */ = {
614
+ isa = PBXTargetDependency;
615
+ target = 2ADB11F6C1D51B9F9A9DB15F /* Klepon */;
616
+ targetProxy = C24CD5A7B8399776539D1FF4 /* PBXContainerItemProxy */;
617
+ };
618
/* End PBXTargetDependency section */
619
620
/* Begin XCBuildConfiguration section */
621
+ 2CE1783225D9E3351FDB458B /* Release */ = {
622
+ isa = XCBuildConfiguration;
623
+ baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
624
+ buildSettings = {
625
+ BUNDLE_LOADER = "$(TEST_HOST)";
626
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
627
+ GENERATE_INFOPLIST_FILE = YES;
628
+ LD_RUNPATH_SEARCH_PATHS = (
629
+ "$(inherited)",
630
+ "@executable_path/Frameworks",
631
+ "@loader_path/Frameworks",
632
+ );
633
+ PRODUCT_BUNDLE_IDENTIFIER = "ai.splitfire.klepon.snapshot-tests";
634
+ SDKROOT = iphoneos;
635
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
636
+ TARGETED_DEVICE_FAMILY = "1,2";
637
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Klepon.app/Klepon";
638
+ };
639
+ name = Release;
640
+ };
641
+ 31056AAA3C7140EC9DD06895 /* Debug */ = {
642
+ isa = XCBuildConfiguration;
643
+ baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
644
+ buildSettings = {
645
+ BUNDLE_LOADER = "$(TEST_HOST)";
646
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
647
+ GENERATE_INFOPLIST_FILE = YES;
648
+ LD_RUNPATH_SEARCH_PATHS = (
649
+ "$(inherited)",
650
+ "@executable_path/Frameworks",
651
+ "@loader_path/Frameworks",
652
+ );
653
+ PRODUCT_BUNDLE_IDENTIFIER = "ai.splitfire.klepon.snapshot-tests";
654
+ SDKROOT = iphoneos;
655
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
656
+ TARGETED_DEVICE_FAMILY = "1,2";
657
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Klepon.app/Klepon";
658
+ };
659
+ name = Debug;
660
+ };
661
57B34C7365523CA3F80ED770 /* Debug */ = {
662
isa = XCBuildConfiguration;
663
baseConfigurationReference = 13B09D700AA047E07E91F6A2 /* Signing.xcconfig */;
@@ -782,6 +889,15 @@
889
defaultConfigurationIsVisible = 0;
890
defaultConfigurationName = Debug;
891
};
892
+ 116221FC6D50F33334387509 /* Build configuration list for PBXNativeTarget "KleponSnapshotTests" */ = {
893
+ isa = XCConfigurationList;
894
+ buildConfigurations = (
895
+ 31056AAA3C7140EC9DD06895 /* Debug */,
896
+ 2CE1783225D9E3351FDB458B /* Release */,
897
+ );
898
+ defaultConfigurationIsVisible = 0;
899
+ defaultConfigurationName = Debug;
900
+ };
901
8911E6C6F25C3A4F99870749 /* Build configuration list for PBXProject "Klepon" */ = {
902
isa = XCConfigurationList;
903
buildConfigurations = (
@@ -803,6 +919,14 @@
919
/* End XCConfigurationList section */
920
921
/* Begin XCRemoteSwiftPackageReference section */
922
+ 85B622113A5DC5A1BD2D123B /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = {
923
+ isa = XCRemoteSwiftPackageReference;
924
+ repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing";
925
+ requirement = {
926
+ kind = upToNextMajorVersion;
927
+ minimumVersion = 1.19.2;
928
+ };
929
+ };
930
AD8C734FB461604D5793769C /* XCRemoteSwiftPackageReference "onde-swift" */ = {
931
isa = XCRemoteSwiftPackageReference;
932
repositoryURL = "https://github.com/ondeinference/onde-swift";
@@ -814,6 +938,11 @@
938
/* End XCRemoteSwiftPackageReference section */
939
940
/* Begin XCSwiftPackageProductDependency section */
941
+ 35214C3FF433B08C1C06C3F7 /* SnapshotTesting */ = {
942
+ isa = XCSwiftPackageProductDependency;
943
+ package = 85B622113A5DC5A1BD2D123B /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */;
944
+ productName = SnapshotTesting;
945
+ };
946
855EE8DF62A7820E77C05D1A /* Onde */ = {
947
isa = XCSwiftPackageProductDependency;
948
package = AD8C734FB461604D5793769C /* XCRemoteSwiftPackageReference "onde-swift" */;
Klepon.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+37
-1
@@ -1,5 +1,5 @@
1
{
2
- "originHash" : "c082d58172ce2493986244137cece2181a09f6e7ac51fc87cffba6270d7d243a",
2
+ "originHash" : "d0bdf11c61d97536644353dced450ae7c6ccf1ed85d3c28d0c13998925fa188d",
3
"pins" : [
4
{
5
"identity" : "onde-swift",
@@ -9,6 +9,42 @@
9
"revision" : "d121bc121c2234964e71569e86cbb93cc750361e",
10
"version" : "1.1.0"
11
}
12
+ },
13
+ {
14
+ "identity" : "swift-custom-dump",
15
+ "kind" : "remoteSourceControl",
16
+ "location" : "https://github.com/pointfreeco/swift-custom-dump",
17
+ "state" : {
18
+ "revision" : "06c57924455064182d6b217f06ebc05d00cb2990",
19
+ "version" : "1.5.0"
20
+ }
21
+ },
22
+ {
23
+ "identity" : "swift-snapshot-testing",
24
+ "kind" : "remoteSourceControl",
25
+ "location" : "https://github.com/pointfreeco/swift-snapshot-testing",
26
+ "state" : {
27
+ "revision" : "ad5e3190cc63dc288f28546f9c6827efc1e9d495",
28
+ "version" : "1.19.2"
29
+ }
30
+ },
31
+ {
32
+ "identity" : "swift-syntax",
33
+ "kind" : "remoteSourceControl",
34
+ "location" : "https://github.com/swiftlang/swift-syntax",
35
+ "state" : {
36
+ "revision" : "9de99a78f099e59caf2b2beec65a4c45d54b2081",
37
+ "version" : "603.0.1"
38
+ }
39
+ },
40
+ {
41
+ "identity" : "xctest-dynamic-overlay",
42
+ "kind" : "remoteSourceControl",
43
+ "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
44
+ "state" : {
45
+ "revision" : "dfd70507def84cb5fb821278448a262c6ff2bbad",
46
+ "version" : "1.9.0"
47
+ }
48
}
49
],
50
"version" : 3
Klepon.xcodeproj/xcshareddata/xcschemes/Klepon.xcscheme
+38
-1
@@ -21,6 +21,20 @@
21
ReferencedContainer = "container:Klepon.xcodeproj">
22
</BuildableReference>
23
</BuildActionEntry>
24
+ <BuildActionEntry
25
+ buildForTesting = "YES"
26
+ buildForRunning = "NO"
27
+ buildForProfiling = "NO"
28
+ buildForArchiving = "NO"
29
+ buildForAnalyzing = "NO">
30
+ <BuildableReference
31
+ BuildableIdentifier = "primary"
32
+ BlueprintIdentifier = "F10E9562BA0BE60A7E000DB0"
33
+ BuildableName = "KleponSnapshotTests.xctest"
34
+ BlueprintName = "KleponSnapshotTests"
35
+ ReferencedContainer = "container:Klepon.xcodeproj">
36
+ </BuildableReference>
37
+ </BuildActionEntry>
38
</BuildActionEntries>
39
</BuildAction>
40
<TestAction
@@ -28,7 +42,8 @@
42
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
43
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
44
shouldUseLaunchSchemeArgsEnv = "YES"
31
- onlyGenerateCoverageForSpecifiedTargets = "NO">
45
+ codeCoverageEnabled = "YES"
46
+ onlyGenerateCoverageForSpecifiedTargets = "YES">
47
<MacroExpansion>
48
<BuildableReference
49
BuildableIdentifier = "primary"
@@ -39,7 +54,29 @@
54
</BuildableReference>
55
</MacroExpansion>
56
<Testables>
57
+ <TestableReference
58
+ skipped = "NO"
59
+ parallelizable = "NO">
60
+ <BuildableReference
61
+ BuildableIdentifier = "primary"
62
+ BlueprintIdentifier = "F10E9562BA0BE60A7E000DB0"
63
+ BuildableName = "KleponSnapshotTests.xctest"
64
+ BlueprintName = "KleponSnapshotTests"
65
+ ReferencedContainer = "container:Klepon.xcodeproj">
66
+ </BuildableReference>
67
+ </TestableReference>
68
</Testables>
69
+ <CommandLineArguments>
70
+ </CommandLineArguments>
71
+ <CodeCoverageTargets>
72
+ <BuildableReference
73
+ BuildableIdentifier = "primary"
74
+ BlueprintIdentifier = "2ADB11F6C1D51B9F9A9DB15F"
75
+ BuildableName = "Klepon.app"
76
+ BlueprintName = "Klepon"
77
+ ReferencedContainer = "container:Klepon.xcodeproj">
78
+ </BuildableReference>
79
+ </CodeCoverageTargets>
80
</TestAction>
81
<LaunchAction
82
buildConfiguration = "Debug"
KleponSnapshotTests/KleponSnapshotTests.swift
new
+88
@@ -0,0 +1,88 @@
1
+import SnapshotTesting
2
+import SwiftUI
3
+import XCTest
4
+
5
+@testable import Klepon
6
+
7
+@MainActor
8
+final class KleponSnapshotTests: XCTestCase {
9
+ override func setUp() {
10
+ super.setUp()
11
+ continueAfterFailure = false
12
+ }
13
+
14
+ func testOnboardingView_defaultState() {
15
+ let guideEngine = OndeGuideEngine()
16
+ let view = OnboardingView(onBrowseFirst: {}, onComplete: {})
17
+ .environmentObject(guideEngine)
18
+
19
+ assertSnapshot(
20
+ of: makeHostingController(view),
21
+ as: .image(on: .iPhoneSe),
22
+ named: "default"
23
+ )
24
+ }
25
+
26
+ func testEmptyStateView() {
27
+ let view = ZStack {
28
+ KleponColor.background.ignoresSafeArea()
29
+
30
+ EmptyStateView(
31
+ title: "No saved dishes yet",
32
+ message:
33
+ "When something looks delicious, save it here so you can come back later.",
34
+ systemImage: "heart"
35
+ )
36
+ .padding(24)
37
+ }
38
+
39
+ assertSnapshot(
40
+ of: makeHostingController(view),
41
+ as: .image(on: .iPhoneSe),
42
+ named: "saved-empty-state"
43
+ )
44
+ }
45
+
46
+ func testGuideArtworkView() {
47
+ let view = ZStack {
48
+ KleponColor.background.ignoresSafeArea()
49
+
50
+ GuideArtworkView(entry: .snapshotFixture, height: 210)
51
+ .padding(24)
52
+ }
53
+
54
+ assertSnapshot(
55
+ of: makeHostingController(view),
56
+ as: .image(on: .iPhoneSe),
57
+ named: "guide-artwork"
58
+ )
59
+ }
60
+
61
+ private func makeHostingController<Content: View>(_ view: Content) -> UIViewController {
62
+ let controller = UIHostingController(rootView: view.preferredColorScheme(.light))
63
+ controller.overrideUserInterfaceStyle = .light
64
+ controller.view.backgroundColor = UIColor(KleponColor.background)
65
+ return controller
66
+ }
67
+}
68
+
69
+extension GuideEntry {
70
+ fileprivate static let snapshotFixture = GuideEntry(
71
+ id: "klepon",
72
+ kind: .dish,
73
+ title: "Klepon",
74
+ subtitle: "Palm sugar-filled rice cake rolled in coconut",
75
+ summary: "A soft, sweet bite with a warm syrupy center.",
76
+ story:
77
+ "Klepon is a beloved Indonesian snack made from glutinous rice flour, filled with palm sugar, and coated in fresh grated coconut.",
78
+ tasteNotes: ["Sweet", "Chewy", "Coconut"],
79
+ highlights: ["Palm sugar center", "Fresh coconut coating"],
80
+ region: "Java",
81
+ aliases: ["Onde-onde kecil"],
82
+ tags: ["Snack", "Dessert", "Traditional"],
83
+ relatedIDs: [],
84
+ suggestedQuestions: ["What does klepon taste like?"],
85
+ imageName: nil,
86
+ isFeatured: true
87
+ )
88
+}
KleponSnapshotTests/__Snapshots__/KleponSnapshotTests/testEmptyStateView.saved-empty-state.png
Binary files /dev/null and b/KleponSnapshotTests/__Snapshots__/KleponSnapshotTests/testEmptyStateView.saved-empty-state.png differ
KleponSnapshotTests/__Snapshots__/KleponSnapshotTests/testGuideArtworkView.guide-artwork.png
Binary files /dev/null and b/KleponSnapshotTests/__Snapshots__/KleponSnapshotTests/testGuideArtworkView.guide-artwork.png differ
KleponSnapshotTests/__Snapshots__/KleponSnapshotTests/testOnboardingView_defaultState.default.png
Binary files /dev/null and b/KleponSnapshotTests/__Snapshots__/KleponSnapshotTests/testOnboardingView_defaultState.default.png differ
project.yml
+34
@@ -11,12 +11,23 @@ packages:
11
Onde:
12
url: https://github.com/ondeinference/onde-swift
13
exactVersion: 1.1.0
14
+ SnapshotTesting:
15
+ url: https://github.com/pointfreeco/swift-snapshot-testing
16
+ from: 1.19.2
17
18
schemes:
19
Klepon:
20
build:
21
targets:
22
Klepon: all
23
+ KleponSnapshotTests: [test]
24
+ test:
25
+ config: Debug
26
+ gatherCoverageData: true
27
+ coverageTargets:
28
+ - Klepon
29
+ targets:
30
+ - name: KleponSnapshotTests
31
run:
32
config: Debug
33
analyze:
@@ -117,6 +128,29 @@ targets:
128
Release:
129
SWIFT_OPTIMIZATION_LEVEL: -O
130
131
+ KleponSnapshotTests:
132
+ type: bundle.unit-test
133
+ platform: iOS
134
+ sources:
135
+ - path: KleponSnapshotTests
136
+ configFiles:
137
+ Debug: Configs/Signing.xcconfig
138
+ Release: Configs/Signing.xcconfig
139
+ dependencies:
140
+ - target: Klepon
141
+ - package: SnapshotTesting
142
+ product: SnapshotTesting
143
+ settings:
144
+ base:
145
+ PRODUCT_BUNDLE_IDENTIFIER: ai.splitfire.klepon.snapshot-tests
146
+ GENERATE_INFOPLIST_FILE: YES
147
+ ENABLE_USER_SCRIPT_SANDBOXING: NO
148
+ configs:
149
+ Debug:
150
+ SWIFT_OPTIMIZATION_LEVEL: -Onone
151
+ Release:
152
+ SWIFT_OPTIMIZATION_LEVEL: -O
153
+
154
KleponWatch:
155
name: Klepon Watch
156
type: application