From dd5e07dfc5100b032c16b4b2c44d3de9b4dc9552 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Mon, 18 Sep 2023 18:25:28 +0200 Subject: [PATCH 01/13] prefire basic implementation force the unit tests to run on iPhone 14 skipping plugin validation archive artifacts better workflow removed the OS restriction lfs custom stencil new test file deleting --- .gitattributes | 1 + .githooks/pre-push | 2 +- .github/workflows/unit_tests.yml | 9 + .prefire.yml | 4 + ElementX.xcodeproj/project.pbxproj | 49 +++++ .../xcshareddata/swiftpm/Package.resolved | 9 + .../View/Style/TimelineStyler.swift | 24 +-- .../Timeline/TimelineItemSender.swift | 2 + ElementX/SupportingFiles/target.yml | 1 + Tools/Prefire/PreviewTests.stencil | 176 ++++++++++++++++++ .../Sources/PreviewTests.generated.swift | 169 +++++++++++++++++ UnitTests/SupportingFiles/target.yml | 7 + fastlane/Fastfile | 4 + project.yml | 3 + 14 files changed, 448 insertions(+), 12 deletions(-) create mode 100644 .prefire.yml create mode 100644 Tools/Prefire/PreviewTests.stencil create mode 100644 UnitTests/Sources/PreviewTests.generated.swift diff --git a/.gitattributes b/.gitattributes index b6757eeffc..a789f295fc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ UITests/Sources/__Snapshots__/** filter=lfs diff=lfs merge=lfs -text UnitTests/Resources/** filter=lfs diff=lfs merge=lfs -text +UnitTests/Sources/__Snapshots__ filter=lfs diff=lfs merge=lfs -text diff --git a/.githooks/pre-push b/.githooks/pre-push index 216e91527e..0f0089bc25 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -1,3 +1,3 @@ #!/bin/sh -command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/pre-push'.\n"; exit 2; } +command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; } git lfs pre-push "$@" diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 43e72959fe..a466c8d7ab 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -41,6 +41,15 @@ jobs: - name: Run tests run: bundle exec fastlane unit_tests + + - name: Archive artifacts + uses: actions/upload-artifact@v3 + if: always() + with: + name: test-output + path: fastlane/test_output + retention-days: 1 + if-no-files-found: ignore - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 diff --git a/.prefire.yml b/.prefire.yml new file mode 100644 index 0000000000..c4baf43d31 --- /dev/null +++ b/.prefire.yml @@ -0,0 +1,4 @@ +test_configuration: + - test_file_path: UnitTests/Sources/PreviewTests.generated.swift + - template_file_path: Tools/Prefire/PreviewTests.stencil + - simulator_device: "iPhone14" diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 8142dcbeae..e617e4e749 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -93,6 +93,7 @@ 1C9BB74711E5F24C77B7FED0 /* RoomMembersListScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AEA0B743847CFA5B3C38EE4 /* RoomMembersListScreenCoordinator.swift */; }; 1D5DC685CED904386C89B7DA /* NSRegularExpresion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */; }; 1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */; }; + 1E1E41721A2F41F6B22F75C1 /* PreviewTests.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8D9D1A18907F0F1A7C49CA /* PreviewTests.generated.swift */; }; 1E59B77A0B2CE83DCC1B203C /* LoginViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A05707BF550D770168A406DB /* LoginViewModelTests.swift */; }; 1F04C63D4FA95948E3F52147 /* FileRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51E3D86A84341C3A0CB8A40 /* FileRoomTimelineView.swift */; }; 1F3232BD368DF430AB433907 /* DesignKit in Frameworks */ = {isa = PBXBuildFile; productRef = A5A56C4F47C368EBE5C5E870 /* DesignKit */; }; @@ -211,6 +212,7 @@ 43F35A7E5703D64DB0519C59 /* ServerSelectionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */; }; 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */; }; 44121202B4A260C98BF615A7 /* RoomMembersListScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */; }; + 44F0E1B576C7599DF8022071 /* Prefire in Frameworks */ = {isa = PBXBuildFile; productRef = 2629CF48B33643CD5F69C612 /* Prefire */; }; 4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */; }; 46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; }; 46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCE3636E3D01477C8B2E9D0 /* ReportContentScreenModels.swift */; }; @@ -393,6 +395,7 @@ 7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */; }; 7F7EA51A9A43125A8CB6AC90 /* NotificationSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D560DDA3B20C82766ACFAD /* NotificationSettingsScreenViewModel.swift */; }; 7FB0BDE26838F1A92782D5E1 /* MediaUploadPreviewScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */; }; + 7FF27DA70D833CFC5724EFC5 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 1CAB56FF1DE17B3E871A0BA2 /* SnapshotTesting */; }; 8024BE37156FF0A95A7A3465 /* AnalyticsPromptUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF11DD57D9FACF2A757AB024 /* AnalyticsPromptUITests.swift */; }; 804C15D8ADE0EA7A5268F58A /* OverridableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648DD1C10E4957CB791FE0B8 /* OverridableAvatarImage.swift */; }; 80D00A7C62AAB44F54725C43 /* PermalinkBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */; }; @@ -1423,6 +1426,7 @@ BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenCoordinator.swift; sourceTree = ""; }; BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreProtocol.swift; sourceTree = ""; }; BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderScreenCoordinator.swift; sourceTree = ""; }; + BF8D9D1A18907F0F1A7C49CA /* PreviewTests.generated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewTests.generated.swift; sourceTree = ""; }; BFDCAC6CAAD65A2C24EA9C4B /* Dictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = ""; }; BFEA446F8618DBA79A9239CC /* MessageForwardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreen.swift; sourceTree = ""; }; C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXAttributeScope.swift; sourceTree = ""; }; @@ -1644,6 +1648,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A7A4BAD642A61DCC41621311 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FF27DA70D833CFC5724EFC5 /* SnapshotTesting in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; BF59B36A7B2DB184B62826F6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1704,6 +1716,7 @@ 36AD4DD4C798E22584ED3200 /* Version in Frameworks */, 36CD6E11B37396E14F032CB6 /* Emojibase in Frameworks */, A0D7E5BD0298A97DCBDCE40B /* WysiwygComposer in Frameworks */, + 44F0E1B576C7599DF8022071 /* Prefire in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2675,6 +2688,7 @@ 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */, D53D6BB7E8E5EC031281872C /* OnboardingScreenViewModelTests.swift */, 6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */, + BF8D9D1A18907F0F1A7C49CA /* PreviewTests.generated.swift */, 086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */, 00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */, 2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */, @@ -3958,13 +3972,18 @@ buildPhases = ( 11F93544B4FC60F78F47D89C /* Sources */, 9B3512762CF4A1D45A79C340 /* Resources */, + A7A4BAD642A61DCC41621311 /* Frameworks */, ); buildRules = ( ); dependencies = ( 0EEC1557A40FBA6DF49D83A2 /* PBXTargetDependency */, + 9A791554EB868FA6F6B95324 /* PBXTargetDependency */, ); name = UnitTests; + packageProductDependencies = ( + 1CAB56FF1DE17B3E871A0BA2 /* SnapshotTesting */, + ); productName = UnitTests; productReference = AAC9344689121887B74877AF /* UnitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -4029,6 +4048,7 @@ A05AF81DDD14AD58CB0E1B9B /* Version */, C05729B1684C331F5FFE9232 /* Emojibase */, CA07D57389DACE18AEB6A5E2 /* WysiwygComposer */, + 2629CF48B33643CD5F69C612 /* Prefire */, ); productName = ElementX; productReference = 4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */; @@ -4157,6 +4177,7 @@ 0CBF57301AA172C21F76CE86 /* XCRemoteSwiftPackageReference "maplibre-gl-native-distribution" */, 80B898A3AD2AC63F3ABFC218 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */, 96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */, + 22E7BA2ED466B74739AB8567 /* XCRemoteSwiftPackageReference "Prefire" */, A08925A9D5E3770DEB9D8509 /* XCRemoteSwiftPackageReference "sentry-cocoa" */, E9C4F3A12AA1F65C13A8C8EB /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */, 6582B5AF3F104B0F7E031E7D /* XCRemoteSwiftPackageReference "SwiftState" */, @@ -4440,6 +4461,7 @@ E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */, 0C26A1588B17DCDE5F490FE3 /* OnboardingScreenViewModelTests.swift in Sources */, 27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */, + 1E1E41721A2F41F6B22F75C1 /* PreviewTests.generated.swift in Sources */, D415764645491F10344FC6AC /* Publisher.swift in Sources */, D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */, 9DD84E014ADFB2DD813022D5 /* RoomDetailsEditScreenViewModelTests.swift in Sources */, @@ -5130,6 +5152,10 @@ target = C0FAEB81CFD9776CD78CE489 /* ElementX */; targetProxy = 6848AF4480814C5F810FB7EB /* PBXContainerItemProxy */; }; + 9A791554EB868FA6F6B95324 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + productRef = B717B96C04D7B6A1212D9EDC /* PrefireTestsPlugin */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -5658,6 +5684,14 @@ minimumVersion = 5.13.0; }; }; + 22E7BA2ED466B74739AB8567 /* XCRemoteSwiftPackageReference "Prefire" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/BarredEwe/Prefire"; + requirement = { + kind = upToNextMinorVersion; + minimumVersion = 1.4.1; + }; + }; 395DE6AE429B7ACC7C7FE31D /* XCRemoteSwiftPackageReference "KZFileWatchers" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/krzysztofzablocki/KZFileWatchers"; @@ -5851,6 +5885,11 @@ package = 701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */; productName = GZIP; }; + 1CAB56FF1DE17B3E871A0BA2 /* SnapshotTesting */ = { + isa = XCSwiftPackageProductDependency; + package = E9C4F3A12AA1F65C13A8C8EB /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; + productName = SnapshotTesting; + }; 21C83087604B154AA30E9A8F /* SnapshotTesting */ = { isa = XCSwiftPackageProductDependency; package = E9C4F3A12AA1F65C13A8C8EB /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */; @@ -5861,6 +5900,11 @@ package = 80B898A3AD2AC63F3ABFC218 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */; productName = MatrixRustSDK; }; + 2629CF48B33643CD5F69C612 /* Prefire */ = { + isa = XCSwiftPackageProductDependency; + package = 22E7BA2ED466B74739AB8567 /* XCRemoteSwiftPackageReference "Prefire" */; + productName = Prefire; + }; 290FDEDA4D764B9F7EBE55A9 /* Algorithms */ = { isa = XCSwiftPackageProductDependency; package = E025F19D013D9BA6C58B37F4 /* XCRemoteSwiftPackageReference "swift-algorithms" */; @@ -6029,6 +6073,11 @@ package = 80B898A3AD2AC63F3ABFC218 /* XCRemoteSwiftPackageReference "matrix-rust-components-swift" */; productName = MatrixRustSDK; }; + B717B96C04D7B6A1212D9EDC /* PrefireTestsPlugin */ = { + isa = XCSwiftPackageProductDependency; + package = 22E7BA2ED466B74739AB8567 /* XCRemoteSwiftPackageReference "Prefire" */; + productName = "plugin:PrefireTestsPlugin"; + }; BA93CD75CCE486660C9040BD /* Collections */ = { isa = XCSwiftPackageProductDependency; package = F76A08D0EA29A07A54F4EB4D /* XCRemoteSwiftPackageReference "swift-collections" */; diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 77358ecebd..c2e2668b3b 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -151,6 +151,15 @@ "version" : "2.0.3" } }, + { + "identity" : "prefire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/BarredEwe/Prefire", + "state" : { + "revision" : "abb8dfa44391b4f47edb4937a4ba124e76270a87", + "version" : "1.4.1" + } + }, { "identity" : "sentry-cocoa", "kind" : "remoteSourceControl", diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift index 8550c43e40..e14ec6f8d7 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift @@ -17,6 +17,8 @@ import Foundation import SwiftUI +import Prefire + // MARK: - TimelineStyler struct TimelineStyler: View { @@ -35,10 +37,10 @@ struct TimelineStyler: View { } } -struct TimelineItemStyler_Previews: PreviewProvider { +struct TimelineItemStyler_Previews: PreviewProvider, PrefireProvider { static let viewModel = RoomScreenViewModel.mock - static let base = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test")) + static let base = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) static let sentNonLast: TextRoomTimelineItem = { var result = base @@ -54,7 +56,7 @@ struct TimelineItemStyler_Previews: PreviewProvider { static let sendingLast: TextRoomTimelineItem = { let id = viewModel.state.timelineViewState.timelineIDs.last ?? UUID().uuidString - var result = TextRoomTimelineItem(id: .init(timelineID: id), timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test")) + var result = TextRoomTimelineItem(id: .init(timelineID: id), timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) result.properties.deliveryStatus = .sending return result }() @@ -67,21 +69,21 @@ struct TimelineItemStyler_Previews: PreviewProvider { static let sentLast: TextRoomTimelineItem = { let id = viewModel.state.timelineViewState.timelineIDs.last ?? UUID().uuidString - let result = TextRoomTimelineItem(id: .init(timelineID: id), timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "Test")) + let result = TextRoomTimelineItem(id: .init(timelineID: id), timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) return result }() - static let ltrString = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "house!")) + static let ltrString = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "house!")) - static let rtlString = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "באמת!")) + static let rtlString = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "באמת!")) - static let ltrStringThatContainsRtl = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "house! -- באמת‏! -- house!")) + static let ltrStringThatContainsRtl = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "house! -- באמת‏! -- house!")) - static let rtlStringThatContainsLtr = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "באמת‏! -- house! -- באמת!")) + static let rtlStringThatContainsLtr = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "באמת‏! -- house! -- באמת!")) - static let ltrStringThatFinishesInRtl = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "house! -- באמת!")) + static let ltrStringThatFinishesInRtl = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "house! -- באמת!")) - static let rtlStringThatFinishesInLtr = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .init(id: UUID().uuidString), content: .init(body: "באמת‏! -- house!")) + static let rtlStringThatFinishesInLtr = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "באמת‏! -- house!")) static var testView: some View { VStack { @@ -115,7 +117,7 @@ struct TimelineItemStyler_Previews: PreviewProvider { .environmentObject(viewModel.context) .environment(\.timelineStyle, .plain) .previewDisplayName("Plain") - + languagesTestView .environmentObject(viewModel.context) .environment(\.timelineStyle, .bubbles) diff --git a/ElementX/Sources/Services/Timeline/TimelineItemSender.swift b/ElementX/Sources/Services/Timeline/TimelineItemSender.swift index 265cb00307..d7321d0a1b 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItemSender.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemSender.swift @@ -17,6 +17,8 @@ import UIKit struct TimelineItemSender: Identifiable, Hashable { + static let test = TimelineItemSender(id: "@test.matrix.org") + let id: String let displayName: String? let avatarURL: URL? diff --git a/ElementX/SupportingFiles/target.yml b/ElementX/SupportingFiles/target.yml index f9f4d81822..f85f6bb614 100644 --- a/ElementX/SupportingFiles/target.yml +++ b/ElementX/SupportingFiles/target.yml @@ -193,6 +193,7 @@ targets: - package: Version - package: Emojibase - package: WysiwygComposer + - package: Prefire sources: - path: ../Sources diff --git a/Tools/Prefire/PreviewTests.stencil b/Tools/Prefire/PreviewTests.stencil new file mode 100644 index 0000000000..9ef0cdc44d --- /dev/null +++ b/Tools/Prefire/PreviewTests.stencil @@ -0,0 +1,176 @@ +// swiftlint:disable all +// swiftformat:disable all + +import XCTest +import SwiftUI +import Prefire + +@testable import SnapshotTesting +#if canImport(AccessibilitySnapshot) + import AccessibilitySnapshot +#endif +{% if argument.mainTarget %} +@testable import {{ argument.mainTarget }} +{% endif %} + +class PreviewTests: XCTestCase { + private let deviceConfig: ViewImageConfig = .iPhoneX + private let simulatorDevice = "{{ argument.simulatorDevice|default:"iPhone15,2" }}" + {% if argument.file %} + + private var file: StaticString { .init(stringLiteral: "{{ argument.file }}") } + {% endif %} + + override func setUp() { + super.setUp() + + checkEnvironments() + UIView.setAnimationsEnabled(false) + } + + {% for type in types.types where type.implements.PrefireProvider or type.based.PrefireProvider or type|annotated:"PrefireProvider" %} + func test_{{ type.name|lowerFirstLetter|replace:"_Previews", "" }}() { + for preview in {{ type.name }}._allPreviews { + assertSnapshots(matching: preview) + } + } + + {% endfor %} + // MARK: Private + + private func assertSnapshots(matching preview: _Preview, testName: String = #function) { + let isScreen = preview.layout == .device + let device = preview.device?.snapshotDevice() ?? deviceConfig + var delay: TimeInterval = 0 + var precision: Float = 0.99 + + let view = preview.content + .onPreferenceChange(DelayPreferenceKey.self) { delay = $0 } + .onPreferenceChange(PrecisionPreferenceKey.self) { precision = $0 } + + let matchingView = isScreen ? AnyView(view) : AnyView(view + .frame(width: device.size?.width) + .fixedSize(horizontal: false, vertical: true) + ) + + assertSnapshot( + matching: matchingView, + as: .prefireImage(precision: { precision }, duration: { delay }, layout: isScreen ? .device(config: device) : .sizeThatFits), + named: preview.displayName{% if argument.file %}, + file: file{% endif %}, + testName: testName + ) + + #if canImport(AccessibilitySnapshot) + let vc = UIHostingController(rootView: matchingView) + vc.view.frame = UIScreen.main.bounds + assertSnapshot( + matching: vc, + as: .wait(for: delay, on: .accessibilityImage(showActivationPoints: .always)), + named: preview.displayName.map { $0 + ".accessibility" }{% if argument.file %}, + file: file{% endif %}, + testName: testName + ) + #endif + } + + /// Check environments to avoid problems with snapshots on different devices or OS. + private func checkEnvironments() { + let deviceModel = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] + let osVersion = ProcessInfo().operatingSystemVersion + guard deviceModel?.contains(simulatorDevice) ?? false else { + fatalError("Switch to using \(simulatorDevice) for these tests.") + } + } +} + +// MARK: - SnapshotTesting + Extensions + +private extension PreviewDevice { + func snapshotDevice() -> ViewImageConfig? { + switch rawValue { + case "iPhone 14", "iPhone 13", "iPhone 12", "iPhone 11", "iPhone 10": + return .iPhoneX + case "iPhone 6", "iPhone 6s", "iPhone 7", "iPhone 8": + return .iPhone8 + case "iPhone 6 Plus", "iPhone 6s Plus", "iPhone 8 Plus": + return .iPhone8Plus + case "iPhone SE (1st generation)", "iPhone SE (2nd generation)": + return .iPhoneSe + default: return nil + } + } +} + +private extension Snapshotting where Value: SwiftUI.View, Format == UIImage { + static func prefireImage( + drawHierarchyInKeyWindow: Bool = false, + precision: @escaping () -> Float, + duration: @escaping () -> TimeInterval, + layout: SwiftUISnapshotLayout = .sizeThatFits, + traits: UITraitCollection = .init() + ) -> Snapshotting { + let config: ViewImageConfig + + switch layout { + #if os(iOS) || os(tvOS) + case let .device(config: deviceConfig): + config = deviceConfig + #endif + case .sizeThatFits: + config = .init(safeArea: .zero, size: nil, traits: traits) + case let .fixed(width: width, height: height): + let size = CGSize(width: width, height: height) + config = .init(safeArea: .zero, size: size, traits: traits) + } + + return SimplySnapshotting(pathExtension: "png", diffing: .prefireImage(precision: precision, scale: traits.displayScale)) + .asyncPullback { view in + var config = config + + let controller: UIViewController + + if config.size != nil { + controller = UIHostingController(rootView: view) + } else { + let hostingController = UIHostingController(rootView: view) + + let maxSize = CGSize.zero + config.size = hostingController.sizeThatFits(in: maxSize) + + controller = hostingController + } + + return Async { callback in + let strategy = snapshotView( + config: config, + drawHierarchyInKeyWindow: drawHierarchyInKeyWindow, + traits: traits, + view: controller.view, + viewController: controller + ) + + let duration = duration() + if duration != .zero { + let expectation = XCTestExpectation(description: "Wait") + DispatchQueue.main.asyncAfter(deadline: .now() + duration) { + expectation.fulfill() + } + _ = XCTWaiter.wait(for: [expectation], timeout: duration + 1) + } + strategy.run(callback) + } + } + } +} + +private extension Diffing where Value == UIImage { + static func prefireImage(precision: @escaping () -> Float, scale: CGFloat?) -> Diffing { + lazy var originalDiffing = Diffing.image(precision: precision(), scale: scale) + return Diffing( + toData: { originalDiffing.toData($0) }, + fromData: { originalDiffing.fromData($0) }, + diff: { originalDiffing.diff($0, $1) } + ) + } +} diff --git a/UnitTests/Sources/PreviewTests.generated.swift b/UnitTests/Sources/PreviewTests.generated.swift new file mode 100644 index 0000000000..5eecea51df --- /dev/null +++ b/UnitTests/Sources/PreviewTests.generated.swift @@ -0,0 +1,169 @@ +// Generated using Sourcery 2.0.1 — https://github.com/krzysztofzablocki/Sourcery +// DO NOT EDIT + +// swiftlint:disable all +// swiftformat:disable all + +import XCTest +import SwiftUI +import Prefire + +@testable import SnapshotTesting +#if canImport(AccessibilitySnapshot) + import AccessibilitySnapshot +#endif +@testable import ElementX + +class PreviewTests: XCTestCase { + private let deviceConfig: ViewImageConfig = .iPhoneX + private let simulatorDevice = "iPhone14" + + override func setUp() { + super.setUp() + + checkEnvironments() + UIView.setAnimationsEnabled(false) + } + + func test_timelineItemStyler() { + for preview in TimelineItemStyler_Previews._allPreviews { + assertSnapshots(matching: preview) + } + } + + // MARK: Private + + private func assertSnapshots(matching preview: _Preview, testName: String = #function) { + let isScreen = preview.layout == .device + let device = preview.device?.snapshotDevice() ?? deviceConfig + var delay: TimeInterval = 0 + var precision: Float = 0.99 + + let view = preview.content + .onPreferenceChange(DelayPreferenceKey.self) { delay = $0 } + .onPreferenceChange(PrecisionPreferenceKey.self) { precision = $0 } + + let matchingView = isScreen ? AnyView(view) : AnyView(view + .frame(width: device.size?.width) + .fixedSize(horizontal: false, vertical: true) + ) + + assertSnapshot( + matching: matchingView, + as: .prefireImage(precision: { precision }, duration: { delay }, layout: isScreen ? .device(config: device) : .sizeThatFits), + named: preview.displayName, + testName: testName + ) + + #if canImport(AccessibilitySnapshot) + let vc = UIHostingController(rootView: matchingView) + vc.view.frame = UIScreen.main.bounds + assertSnapshot( + matching: vc, + as: .wait(for: delay, on: .accessibilityImage(showActivationPoints: .always)), + named: preview.displayName.map { $0 + ".accessibility" }, + testName: testName + ) + #endif + } + + /// Check environments to avoid problems with snapshots on different devices or OS. + private func checkEnvironments() { + let deviceModel = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] + let osVersion = ProcessInfo().operatingSystemVersion + guard deviceModel?.contains(simulatorDevice) ?? false else { + fatalError("Switch to using \(simulatorDevice) for these tests.") + } + } +} + +// MARK: - SnapshotTesting + Extensions + +private extension PreviewDevice { + func snapshotDevice() -> ViewImageConfig? { + switch rawValue { + case "iPhone 14", "iPhone 13", "iPhone 12", "iPhone 11", "iPhone 10": + return .iPhoneX + case "iPhone 6", "iPhone 6s", "iPhone 7", "iPhone 8": + return .iPhone8 + case "iPhone 6 Plus", "iPhone 6s Plus", "iPhone 8 Plus": + return .iPhone8Plus + case "iPhone SE (1st generation)", "iPhone SE (2nd generation)": + return .iPhoneSe + default: return nil + } + } +} + +private extension Snapshotting where Value: SwiftUI.View, Format == UIImage { + static func prefireImage( + drawHierarchyInKeyWindow: Bool = false, + precision: @escaping () -> Float, + duration: @escaping () -> TimeInterval, + layout: SwiftUISnapshotLayout = .sizeThatFits, + traits: UITraitCollection = .init() + ) -> Snapshotting { + let config: ViewImageConfig + + switch layout { + #if os(iOS) || os(tvOS) + case let .device(config: deviceConfig): + config = deviceConfig + #endif + case .sizeThatFits: + config = .init(safeArea: .zero, size: nil, traits: traits) + case let .fixed(width: width, height: height): + let size = CGSize(width: width, height: height) + config = .init(safeArea: .zero, size: size, traits: traits) + } + + return SimplySnapshotting(pathExtension: "png", diffing: .prefireImage(precision: precision, scale: traits.displayScale)) + .asyncPullback { view in + var config = config + + let controller: UIViewController + + if config.size != nil { + controller = UIHostingController(rootView: view) + } else { + let hostingController = UIHostingController(rootView: view) + + let maxSize = CGSize.zero + config.size = hostingController.sizeThatFits(in: maxSize) + + controller = hostingController + } + + return Async { callback in + let strategy = snapshotView( + config: config, + drawHierarchyInKeyWindow: drawHierarchyInKeyWindow, + traits: traits, + view: controller.view, + viewController: controller + ) + + let duration = duration() + if duration != .zero { + let expectation = XCTestExpectation(description: "Wait") + DispatchQueue.main.asyncAfter(deadline: .now() + duration) { + expectation.fulfill() + } + _ = XCTWaiter.wait(for: [expectation], timeout: duration + 1) + } + strategy.run(callback) + } + } + } +} + +private extension Diffing where Value == UIImage { + static func prefireImage(precision: @escaping () -> Float, scale: CGFloat?) -> Diffing { + lazy var originalDiffing = Diffing.image(precision: precision(), scale: scale) + return Diffing( + toData: { originalDiffing.toData($0) }, + fromData: { originalDiffing.fromData($0) }, + diff: { originalDiffing.diff($0, $1) } + ) + } +} diff --git a/UnitTests/SupportingFiles/target.yml b/UnitTests/SupportingFiles/target.yml index f24d2827e5..19fd5d4b29 100644 --- a/UnitTests/SupportingFiles/target.yml +++ b/UnitTests/SupportingFiles/target.yml @@ -28,9 +28,14 @@ targets: UnitTests: type: bundle.unit-test platform: iOS + + buildToolPlugins: + - plugin: PrefireTestsPlugin + package: Prefire dependencies: - target: ElementX + - package: SnapshotTesting info: path: ../SupportingFiles/Info.plist @@ -44,6 +49,8 @@ targets: sources: - path: ../Sources + excludes: + - "**/__Snapshots__/**" - path: ../SupportingFiles - path: ../../ElementX/Sources/Other/InfoPlistReader.swift - path: ../../Tools/Scripts/Templates/SimpleScreenExample/Tests/Unit diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 76da99a609..bb4df55d72 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -77,8 +77,12 @@ end lane :unit_tests do run_tests( scheme: "UnitTests", + devices: ["iPhone 14"], + ensure_devices_found: true, + prelaunch_simulator: true, result_bundle: true, number_of_retries: 3, + xcargs: '-skipPackagePluginValidation', ) slather( diff --git a/project.yml b/project.yml index 30f35b084a..9a832e4640 100644 --- a/project.yml +++ b/project.yml @@ -94,6 +94,9 @@ packages: PostHog: url: https://github.com/PostHog/posthog-ios minorVersion: 2.0.3 + Prefire: + url: https://github.com/BarredEwe/Prefire + minorVersion: 1.4.1 Sentry: url: https://github.com/getsentry/sentry-cocoa minorVersion: 8.6.0 From 94856876b471a65b2a99ae480ec7e79a4f408189 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 12:03:07 +0200 Subject: [PATCH 02/13] git lfs --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index a789f295fc..16b40980fd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ UITests/Sources/__Snapshots__/** filter=lfs diff=lfs merge=lfs -text UnitTests/Resources/** filter=lfs diff=lfs merge=lfs -text UnitTests/Sources/__Snapshots__ filter=lfs diff=lfs merge=lfs -text +UnitTests/Sources/__Snapshots__/PreviewTests.generated filter=lfs diff=lfs merge=lfs -text From 7e7b621bcdd21452f26e914f6e26e9e2c8d31476 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 12:04:45 +0200 Subject: [PATCH 03/13] lfs --- .gitattributes | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitattributes b/.gitattributes index 16b40980fd..b59f2b141d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,3 @@ UITests/Sources/__Snapshots__/** filter=lfs diff=lfs merge=lfs -text UnitTests/Resources/** filter=lfs diff=lfs merge=lfs -text -UnitTests/Sources/__Snapshots__ filter=lfs diff=lfs merge=lfs -text -UnitTests/Sources/__Snapshots__/PreviewTests.generated filter=lfs diff=lfs merge=lfs -text +UnitTests/Sources/__Snapshots__/** filter=lfs diff=lfs merge=lfs -text \ No newline at end of file From 0dbfaccd403f79f7408e6b43d4781557d2897385 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 12:07:09 +0200 Subject: [PATCH 04/13] test --- ...eItemStyler.Bubbles-LTR-with-different-layout-languages.png | 3 +++ ...eItemStyler.Bubbles-RTL-with-different-layout-languages.png | 3 +++ .../PreviewTests.generated/test_timelineItemStyler.Bubbles.png | 3 +++ .../PreviewTests.generated/test_timelineItemStyler.Plain.png | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles.png create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Plain.png diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png new file mode 100644 index 0000000000..602235eaf5 --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c935c6529a9f9a63915c3cab80dc9fc7df8723db6258c4d8c445df7c84296e65 +size 110159 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png new file mode 100644 index 0000000000..ec57afe2dc --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebec20c376958c8a4b10a4055f15963a27ed744e0ac594aae803b0e56c6477a2 +size 108424 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles.png b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles.png new file mode 100644 index 0000000000..55ef75591a --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f84bcc4acb59ef1a6fb5893b0840b32e3011e6a1e66004b65650ab30321b7f8 +size 97748 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Plain.png b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Plain.png new file mode 100644 index 0000000000..ef91578a53 --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Plain.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b2f89b01650704e45b0c9a57c67f7fbe4cf583299b6d0392b4d79c22725a3f7 +size 132101 From 7106b3c1734fcee828334585eec5a12de83f67c1 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 12:22:16 +0200 Subject: [PATCH 05/13] customised the stencil to support our internal protocol --- .swiftlint.yml | 3 +++ ElementX.xcodeproj/project.pbxproj | 20 +++++++++++------- ElementX/Sources/Other/TestablePreview.swift | 21 +++++++++++++++++++ .../View/Style/TimelineStyler.swift | 4 +--- Tools/Prefire/PreviewTests.stencil | 2 +- 5 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 ElementX/Sources/Other/TestablePreview.swift diff --git a/.swiftlint.yml b/.swiftlint.yml index b304435f39..6c8d311864 100755 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -47,6 +47,9 @@ cyclomatic_complexity: nesting: type_level: warning: 5 + +type_name: + allowed_symbols: "_" custom_rules: print_deprecation: diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index e617e4e749..ecc8afe7dc 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 56; objects = { /* Begin PBXBuildFile section */ @@ -536,6 +536,7 @@ A6DEC1ADEC8FEEC206A0FA37 /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; }; A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; }; A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; }; + A7C400D12AB9ABDA0038D99A /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C400D02AB9ABDA0038D99A /* TestablePreview.swift */; }; A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; A7FD7B992E6EE6E5A8429197 /* RoomSummaryDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142808B69851451AC32A2CEA /* RoomSummaryDetails.swift */; }; A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; }; @@ -934,7 +935,7 @@ 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentValuePublisher.swift; sourceTree = ""; }; 12EDAFB64FA5F6812D54F39A /* MigrationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModel.swift; sourceTree = ""; }; 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenCoordinator.swift; sourceTree = ""; }; - 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = ""; }; + 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = ""; }; 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = ""; }; 13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; 1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = ""; }; @@ -1086,7 +1087,7 @@ 47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = ""; }; 471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = ""; }; 47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = ""; }; - 478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = DesignKit; path = DesignKit; sourceTree = SOURCE_ROOT; }; + 478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DesignKit; sourceTree = SOURCE_ROOT; }; 4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = ""; }; 47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; }; 47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = ""; }; @@ -1283,7 +1284,7 @@ 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; 8E1BBA73B611EDEEA6E20E05 /* InvitesScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenModels.swift; sourceTree = ""; }; 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenUITests.swift; sourceTree = ""; }; 8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = ""; }; @@ -1353,6 +1354,7 @@ A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = ""; }; A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHGPostHogConfiguration.swift; sourceTree = ""; }; A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = ""; }; + A7C400D02AB9ABDA0038D99A /* TestablePreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestablePreview.swift; sourceTree = ""; }; A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = ""; }; A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenCoordinator.swift; sourceTree = ""; }; A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationProtocol.swift; sourceTree = ""; }; @@ -1396,7 +1398,7 @@ B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = ""; }; B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = ""; }; B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = ""; }; - B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = ""; }; + B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = ""; }; B6311F21F911E23BE4DF51B4 /* ReadMarkerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineView.swift; sourceTree = ""; }; B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; B697816AF93DA06EC58C5D70 /* WaitlistScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -1488,7 +1490,7 @@ CD95B3714F806AC9CF9A557B /* ComposerToolbarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbarViewModel.swift; sourceTree = ""; }; CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = ""; }; CEE0E6043EFCF6FD2A341861 /* TimelineReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReplyView.swift; sourceTree = ""; }; - CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = ""; }; + CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxy.swift; sourceTree = ""; }; D0140615D2232612C813FD6C /* EncryptedHistoryRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedHistoryRoomTimelineItem.swift; sourceTree = ""; }; D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = ""; }; @@ -1574,7 +1576,7 @@ ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModel.swift; sourceTree = ""; }; ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = ""; }; ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = ""; }; - ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = ""; }; + ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = ""; }; ED983D4DCA5AFA6E1ED96099 /* StateRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRoomTimelineView.swift; sourceTree = ""; }; EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = ""; }; EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = ""; }; @@ -1588,7 +1590,7 @@ F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = ""; }; F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProvider.swift; sourceTree = ""; }; F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = ""; }; - F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; path = portrait_test_video.mp4; sourceTree = ""; }; + F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = portrait_test_video.mp4; sourceTree = ""; }; F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegexTests.swift; sourceTree = ""; }; F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItem.swift; sourceTree = ""; }; F36C0A6D59717193F49EA986 /* UserSessionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionTests.swift; sourceTree = ""; }; @@ -3522,6 +3524,7 @@ 9C4193C4524B35FD6B94B5A9 /* Pills */, 052CC920F473C10B509F9FC1 /* SwiftUI */, B687E3E8C23415A06A3D5C65 /* UserIndicator */, + A7C400D02AB9ABDA0038D99A /* TestablePreview.swift */, ); path = Other; sourceTree = ""; @@ -4981,6 +4984,7 @@ 53F1196F9C69512306A2693F /* TextRoomTimelineItemContent.swift in Sources */, 5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */, 5B2D1210B40570D87B11BD3B /* ThreadDecorator.swift in Sources */, + A7C400D12AB9ABDA0038D99A /* TestablePreview.swift in Sources */, 43EF6D8E694F54C5471BF5F3 /* TimelineBubbleLayout.swift in Sources */, 5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */, 157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */, diff --git a/ElementX/Sources/Other/TestablePreview.swift b/ElementX/Sources/Other/TestablePreview.swift new file mode 100644 index 0000000000..2b92315eed --- /dev/null +++ b/ElementX/Sources/Other/TestablePreview.swift @@ -0,0 +1,21 @@ +// +// Copyright 2023 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +import Prefire + +protocol TestablePreviewProvider: PreviewProvider, PrefireProvider { } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift index e14ec6f8d7..06e754e42c 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Style/TimelineStyler.swift @@ -17,8 +17,6 @@ import Foundation import SwiftUI -import Prefire - // MARK: - TimelineStyler struct TimelineStyler: View { @@ -37,7 +35,7 @@ struct TimelineStyler: View { } } -struct TimelineItemStyler_Previews: PreviewProvider, PrefireProvider { +struct TimelineItemStyler_Previews: TestablePreviewProvider { static let viewModel = RoomScreenViewModel.mock static let base = TextRoomTimelineItem(id: .random, timestamp: "Now", isOutgoing: true, isEditable: false, isThreaded: false, sender: .test, content: .init(body: "Test")) diff --git a/Tools/Prefire/PreviewTests.stencil b/Tools/Prefire/PreviewTests.stencil index 9ef0cdc44d..a42728db5b 100644 --- a/Tools/Prefire/PreviewTests.stencil +++ b/Tools/Prefire/PreviewTests.stencil @@ -28,7 +28,7 @@ class PreviewTests: XCTestCase { UIView.setAnimationsEnabled(false) } - {% for type in types.types where type.implements.PrefireProvider or type.based.PrefireProvider or type|annotated:"PrefireProvider" %} + {% for type in types.types where (type.implements.PrefireProvider or type.based.PrefireProvider or type|annotated:"PrefireProvider") and type.name != "TestablePreviewProvider" %} func test_{{ type.name|lowerFirstLetter|replace:"_Previews", "" }}() { for preview in {{ type.name }}._allPreviews { assertSnapshots(matching: preview) From f83a1889ef89fca815bcde2140b8f61337a55f9b Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 12:40:49 +0200 Subject: [PATCH 06/13] for now we can remove the OS check from the stencil --- Tools/Prefire/PreviewTests.stencil | 1 - UnitTests/Sources/PreviewTests.generated.swift | 1 - 2 files changed, 2 deletions(-) diff --git a/Tools/Prefire/PreviewTests.stencil b/Tools/Prefire/PreviewTests.stencil index a42728db5b..7914ff9346 100644 --- a/Tools/Prefire/PreviewTests.stencil +++ b/Tools/Prefire/PreviewTests.stencil @@ -77,7 +77,6 @@ class PreviewTests: XCTestCase { /// Check environments to avoid problems with snapshots on different devices or OS. private func checkEnvironments() { let deviceModel = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] - let osVersion = ProcessInfo().operatingSystemVersion guard deviceModel?.contains(simulatorDevice) ?? false else { fatalError("Switch to using \(simulatorDevice) for these tests.") } diff --git a/UnitTests/Sources/PreviewTests.generated.swift b/UnitTests/Sources/PreviewTests.generated.swift index 5eecea51df..81a5091df9 100644 --- a/UnitTests/Sources/PreviewTests.generated.swift +++ b/UnitTests/Sources/PreviewTests.generated.swift @@ -70,7 +70,6 @@ class PreviewTests: XCTestCase { /// Check environments to avoid problems with snapshots on different devices or OS. private func checkEnvironments() { let deviceModel = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] - let osVersion = ProcessInfo().operatingSystemVersion guard deviceModel?.contains(simulatorDevice) ?? false else { fatalError("Switch to using \(simulatorDevice) for these tests.") } From e463778a238769ed57d6bcc002f6619d8e72af15 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 13:29:38 +0200 Subject: [PATCH 07/13] added a delay --- .prefire.yml | 2 +- ElementX.xcodeproj/project.pbxproj | 32 +++++++++---------- Tools/Prefire/PreviewTests.stencil | 2 +- ...sts.generated.swift => PreviewTests.swift} | 2 +- fastlane/Fastfile | 1 - 5 files changed, 19 insertions(+), 20 deletions(-) rename UnitTests/Sources/{PreviewTests.generated.swift => PreviewTests.swift} (99%) diff --git a/.prefire.yml b/.prefire.yml index c4baf43d31..7a57aae92f 100644 --- a/.prefire.yml +++ b/.prefire.yml @@ -1,4 +1,4 @@ test_configuration: - - test_file_path: UnitTests/Sources/PreviewTests.generated.swift + - test_file_path: UnitTests/Sources/PreviewTests.swift - template_file_path: Tools/Prefire/PreviewTests.stencil - simulator_device: "iPhone14" diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index ecc8afe7dc..65f276241f 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 56; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -93,7 +93,6 @@ 1C9BB74711E5F24C77B7FED0 /* RoomMembersListScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AEA0B743847CFA5B3C38EE4 /* RoomMembersListScreenCoordinator.swift */; }; 1D5DC685CED904386C89B7DA /* NSRegularExpresion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */; }; 1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11151E78D6BB2B04A8FBD389 /* EmojiPickerScreenViewModelProtocol.swift */; }; - 1E1E41721A2F41F6B22F75C1 /* PreviewTests.generated.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8D9D1A18907F0F1A7C49CA /* PreviewTests.generated.swift */; }; 1E59B77A0B2CE83DCC1B203C /* LoginViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A05707BF550D770168A406DB /* LoginViewModelTests.swift */; }; 1F04C63D4FA95948E3F52147 /* FileRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51E3D86A84341C3A0CB8A40 /* FileRoomTimelineView.swift */; }; 1F3232BD368DF430AB433907 /* DesignKit in Frameworks */ = {isa = PBXBuildFile; productRef = A5A56C4F47C368EBE5C5E870 /* DesignKit */; }; @@ -301,6 +300,7 @@ 62910B515BCB4B455E24D7C1 /* AdvancedSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D086854995173E897F993C26 /* AdvancedSettingsScreenViewModelProtocol.swift */; }; 6298AB0906DDD3525CD78C6B /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = 81DB3AB6CE996AB3954F4F03 /* KZFileWatchers */; }; 63E46D18B91D08E15FC04125 /* ExpiringTaskRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B25F959A434BB9923A3223F /* ExpiringTaskRunner.swift */; }; + 642DF13C49ED4121C148230E /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E227F34BE43B08E098796E /* TestablePreview.swift */; }; 6448F8D1D3CA4CD27BB4CADD /* RoomMemberProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F36C5D9B37E50915ECBD3EE /* RoomMemberProxy.swift */; }; 644AA5001BCC58D7732EB772 /* MigrationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12EDAFB64FA5F6812D54F39A /* MigrationScreenViewModel.swift */; }; 64C373ACCFA26D42BA45CFAD /* HomeScreenInvitesButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24227FF9A2797F6EA7F69CDD /* HomeScreenInvitesButton.swift */; }; @@ -492,6 +492,7 @@ 9BEA56957B3AF954E7321658 /* ComposerToolbarViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E44928D844E16EE48A311FCA /* ComposerToolbarViewModelProtocol.swift */; }; 9C45CE85325CD591DADBC4CA /* ElementXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */; }; 9C5A07E7C33F3F40287D7861 /* SettingsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */; }; + 9C7895941669EA7976A18D88 /* PreviewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A01505B6371171413C3C4BD /* PreviewTests.swift */; }; 9CCC77C31CB399661A034739 /* UserProperties+Element.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A6C4BE591FE5C38CE9C7EF3 /* UserProperties+Element.swift */; }; 9D2E03DB175A6AB14589076D /* Algorithms in Frameworks */ = {isa = PBXBuildFile; productRef = 290FDEDA4D764B9F7EBE55A9 /* Algorithms */; }; 9D79B94493FB32249F7E472F /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C705E605EF57C19DBE86FFA1 /* PlaceholderAvatarImage.swift */; }; @@ -536,7 +537,6 @@ A6DEC1ADEC8FEEC206A0FA37 /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; }; A722F426FD81FC67706BB1E0 /* CustomLayoutLabelStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42236480CF0431535EBE8387 /* CustomLayoutLabelStyle.swift */; }; A74438ED16F8683A4B793E6A /* AnalyticsSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BCE3FAF40932AC7C7639AC4 /* AnalyticsSettingsScreenViewModel.swift */; }; - A7C400D12AB9ABDA0038D99A /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C400D02AB9ABDA0038D99A /* TestablePreview.swift */; }; A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; A7FD7B992E6EE6E5A8429197 /* RoomSummaryDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142808B69851451AC32A2CEA /* RoomSummaryDetails.swift */; }; A816F7087C495D85048AC50E /* RoomMemberDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B6E30BB748F3F480F077969 /* RoomMemberDetailsScreenModels.swift */; }; @@ -935,7 +935,7 @@ 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentValuePublisher.swift; sourceTree = ""; }; 12EDAFB64FA5F6812D54F39A /* MigrationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModel.swift; sourceTree = ""; }; 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenCoordinator.swift; sourceTree = ""; }; - 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = ""; }; + 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = ""; }; 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = ""; }; 13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; 1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = ""; }; @@ -1087,7 +1087,7 @@ 47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = ""; }; 471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = ""; }; 47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = ""; }; - 478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DesignKit; sourceTree = SOURCE_ROOT; }; + 478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = DesignKit; path = DesignKit; sourceTree = SOURCE_ROOT; }; 4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = ""; }; 47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; }; 47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = ""; }; @@ -1097,6 +1097,7 @@ 49E45C3DC740D3AB9A47FD32 /* SwipeToReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeToReplyView.swift; sourceTree = ""; }; 49E6066092ED45E36BB306F7 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.stringsdict"; sourceTree = ""; }; 49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationRequest.swift; sourceTree = ""; }; + 4A01505B6371171413C3C4BD /* PreviewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewTests.swift; sourceTree = ""; }; 4A4AD793D50748F8997E5B15 /* TimelineItemMacContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMacContextMenu.swift; sourceTree = ""; }; 4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaLoader.swift; sourceTree = ""; }; 4ADC55DFF46083BC957E0019 /* CreatePollScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePollScreenModels.swift; sourceTree = ""; }; @@ -1284,7 +1285,7 @@ 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; 8E1BBA73B611EDEEA6E20E05 /* InvitesScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenModels.swift; sourceTree = ""; }; 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenUITests.swift; sourceTree = ""; }; 8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = ""; }; @@ -1354,7 +1355,6 @@ A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = ""; }; A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHGPostHogConfiguration.swift; sourceTree = ""; }; A73A07BAEDD74C48795A996A /* AsyncSequence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncSequence.swift; sourceTree = ""; }; - A7C400D02AB9ABDA0038D99A /* TestablePreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestablePreview.swift; sourceTree = ""; }; A7C4EA55DA62F9D0F984A2AE /* CollapsibleTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleTimelineItem.swift; sourceTree = ""; }; A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenCoordinator.swift; sourceTree = ""; }; A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationProtocol.swift; sourceTree = ""; }; @@ -1388,6 +1388,7 @@ B0A307A44F952CD73E63AE31 /* RoomEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomEventStringBuilder.swift; sourceTree = ""; }; B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRoomTimelineItem.swift; sourceTree = ""; }; B16CAF20C9AC874A210E2DCF /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = ""; }; + B1E227F34BE43B08E098796E /* TestablePreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestablePreview.swift; sourceTree = ""; }; B251F5B4511D1CA0BA8361FE /* CoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinatorProtocol.swift; sourceTree = ""; }; B2B5EDCD05D50BA9B815C66C /* ImageRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItemContent.swift; sourceTree = ""; }; B2E7C987AE5DC9087BB19F7D /* MediaUploadPreviewScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenModels.swift; sourceTree = ""; }; @@ -1398,7 +1399,7 @@ B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = ""; }; B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = ""; }; B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = ""; }; - B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = ""; }; + B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = ""; }; B6311F21F911E23BE4DF51B4 /* ReadMarkerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineView.swift; sourceTree = ""; }; B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; B697816AF93DA06EC58C5D70 /* WaitlistScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -1428,7 +1429,6 @@ BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenCoordinator.swift; sourceTree = ""; }; BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreProtocol.swift; sourceTree = ""; }; BF34A2FD6797535C95AC918D /* PlaceholderScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderScreenCoordinator.swift; sourceTree = ""; }; - BF8D9D1A18907F0F1A7C49CA /* PreviewTests.generated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewTests.generated.swift; sourceTree = ""; }; BFDCAC6CAAD65A2C24EA9C4B /* Dictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = ""; }; BFEA446F8618DBA79A9239CC /* MessageForwardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreen.swift; sourceTree = ""; }; C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXAttributeScope.swift; sourceTree = ""; }; @@ -1490,7 +1490,7 @@ CD95B3714F806AC9CF9A557B /* ComposerToolbarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbarViewModel.swift; sourceTree = ""; }; CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = ""; }; CEE0E6043EFCF6FD2A341861 /* TimelineReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReplyView.swift; sourceTree = ""; }; - CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; + CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = ""; }; CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxy.swift; sourceTree = ""; }; D0140615D2232612C813FD6C /* EncryptedHistoryRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedHistoryRoomTimelineItem.swift; sourceTree = ""; }; D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = ""; }; @@ -1576,7 +1576,7 @@ ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModel.swift; sourceTree = ""; }; ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = ""; }; ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = ""; }; - ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = ""; }; + ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = ""; }; ED983D4DCA5AFA6E1ED96099 /* StateRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRoomTimelineView.swift; sourceTree = ""; }; EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = ""; }; EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = ""; }; @@ -1590,7 +1590,7 @@ F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = ""; }; F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProvider.swift; sourceTree = ""; }; F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = ""; }; - F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = portrait_test_video.mp4; sourceTree = ""; }; + F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; path = portrait_test_video.mp4; sourceTree = ""; }; F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegexTests.swift; sourceTree = ""; }; F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItem.swift; sourceTree = ""; }; F36C0A6D59717193F49EA986 /* UserSessionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionTests.swift; sourceTree = ""; }; @@ -2690,7 +2690,7 @@ 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */, D53D6BB7E8E5EC031281872C /* OnboardingScreenViewModelTests.swift */, 6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */, - BF8D9D1A18907F0F1A7C49CA /* PreviewTests.generated.swift */, + 4A01505B6371171413C3C4BD /* PreviewTests.swift */, 086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */, 00E5B2CBEF8F96424F095508 /* RoomDetailsEditScreenViewModelTests.swift */, 2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */, @@ -3511,6 +3511,7 @@ 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */, DBA8DC95C079805B0B56E8A9 /* SharedUserDefaultsKeys.swift */, 4481799F455B3DA243BDA2AC /* ShareToMapsAppActivity.swift */, + B1E227F34BE43B08E098796E /* TestablePreview.swift */, BB3073CCD77D906B330BC1D6 /* Tests.swift */, 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */, 35FA991289149D31F4286747 /* UserPreference.swift */, @@ -3524,7 +3525,6 @@ 9C4193C4524B35FD6B94B5A9 /* Pills */, 052CC920F473C10B509F9FC1 /* SwiftUI */, B687E3E8C23415A06A3D5C65 /* UserIndicator */, - A7C400D02AB9ABDA0038D99A /* TestablePreview.swift */, ); path = Other; sourceTree = ""; @@ -4464,7 +4464,7 @@ E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */, 0C26A1588B17DCDE5F490FE3 /* OnboardingScreenViewModelTests.swift in Sources */, 27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */, - 1E1E41721A2F41F6B22F75C1 /* PreviewTests.generated.swift in Sources */, + 9C7895941669EA7976A18D88 /* PreviewTests.swift in Sources */, D415764645491F10344FC6AC /* Publisher.swift in Sources */, D53B80EF02C1062E68659EDD /* ReportContentViewModelTests.swift in Sources */, 9DD84E014ADFB2DD813022D5 /* RoomDetailsEditScreenViewModelTests.swift in Sources */, @@ -4977,6 +4977,7 @@ CCBEC2100CAF2EEBE9DB4156 /* TemplateScreenModels.swift in Sources */, 275EDE8849A2AC1D9309ED7C /* TemplateScreenViewModel.swift in Sources */, 2C4C750D0039AFABDF24236C /* TemplateScreenViewModelProtocol.swift in Sources */, + 642DF13C49ED4121C148230E /* TestablePreview.swift in Sources */, D85D4FA590305180B4A41795 /* Tests.swift in Sources */, 8317E1314C00DCCC99D30DA8 /* TextBasedRoomTimelineItem.swift in Sources */, A2A5AB2E8B3F5CA769E531FA /* TextBasedRoomTimelineViewProtocol.swift in Sources */, @@ -4984,7 +4985,6 @@ 53F1196F9C69512306A2693F /* TextRoomTimelineItemContent.swift in Sources */, 5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */, 5B2D1210B40570D87B11BD3B /* ThreadDecorator.swift in Sources */, - A7C400D12AB9ABDA0038D99A /* TestablePreview.swift in Sources */, 43EF6D8E694F54C5471BF5F3 /* TimelineBubbleLayout.swift in Sources */, 5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */, 157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */, diff --git a/Tools/Prefire/PreviewTests.stencil b/Tools/Prefire/PreviewTests.stencil index 7914ff9346..086eb13180 100644 --- a/Tools/Prefire/PreviewTests.stencil +++ b/Tools/Prefire/PreviewTests.stencil @@ -41,7 +41,7 @@ class PreviewTests: XCTestCase { private func assertSnapshots(matching preview: _Preview, testName: String = #function) { let isScreen = preview.layout == .device let device = preview.device?.snapshotDevice() ?? deviceConfig - var delay: TimeInterval = 0 + var delay: TimeInterval = 1.0 var precision: Float = 0.99 let view = preview.content diff --git a/UnitTests/Sources/PreviewTests.generated.swift b/UnitTests/Sources/PreviewTests.swift similarity index 99% rename from UnitTests/Sources/PreviewTests.generated.swift rename to UnitTests/Sources/PreviewTests.swift index 81a5091df9..d5ff971500 100644 --- a/UnitTests/Sources/PreviewTests.generated.swift +++ b/UnitTests/Sources/PreviewTests.swift @@ -36,7 +36,7 @@ class PreviewTests: XCTestCase { private func assertSnapshots(matching preview: _Preview, testName: String = #function) { let isScreen = preview.layout == .device let device = preview.device?.snapshotDevice() ?? deviceConfig - var delay: TimeInterval = 0 + var delay: TimeInterval = 1.0 var precision: Float = 0.99 let view = preview.content diff --git a/fastlane/Fastfile b/fastlane/Fastfile index bb4df55d72..4f63335ae0 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -79,7 +79,6 @@ lane :unit_tests do scheme: "UnitTests", devices: ["iPhone 14"], ensure_devices_found: true, - prelaunch_simulator: true, result_bundle: true, number_of_retries: 3, xcargs: '-skipPackagePluginValidation', From c66867498881f5c452eb07bedb0bc5df35bb9dab Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 14:30:49 +0200 Subject: [PATCH 08/13] tests have been moved --- ...lineItemStyler.Bubbles-LTR-with-different-layout-languages.png | 0 ...lineItemStyler.Bubbles-RTL-with-different-layout-languages.png | 0 .../test_timelineItemStyler.Bubbles.png | 0 .../test_timelineItemStyler.Plain.png | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename UnitTests/Sources/__Snapshots__/{PreviewTests.generated => PreviewTests}/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png (100%) rename UnitTests/Sources/__Snapshots__/{PreviewTests.generated => PreviewTests}/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png (100%) rename UnitTests/Sources/__Snapshots__/{PreviewTests.generated => PreviewTests}/test_timelineItemStyler.Bubbles.png (100%) rename UnitTests/Sources/__Snapshots__/{PreviewTests.generated => PreviewTests}/test_timelineItemStyler.Plain.png (100%) diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png similarity index 100% rename from UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png rename to UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png similarity index 100% rename from UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png rename to UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png similarity index 100% rename from UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Bubbles.png rename to UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Plain.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png similarity index 100% rename from UnitTests/Sources/__Snapshots__/PreviewTests.generated/test_timelineItemStyler.Plain.png rename to UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png From 73dab56b5e1cedde519f9493048d8043c39fd1e0 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 14:31:24 +0200 Subject: [PATCH 09/13] improvement --- .github/workflows/unit_tests.yml | 3 ++- ...eItemStyler.Bubbles-LTR-with-different-layout-languages.png | 3 --- ...eItemStyler.Bubbles-RTL-with-different-layout-languages.png | 3 --- .../PreviewTests/test_timelineItemStyler.Bubbles.png | 3 --- .../PreviewTests/test_timelineItemStyler.Plain.png | 3 --- 5 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png delete mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png delete mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png delete mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index a466c8d7ab..276df1470d 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -44,7 +44,8 @@ jobs: - name: Archive artifacts uses: actions/upload-artifact@v3 - if: always() + # We only care about artifcats if the tests fail + if: failure() with: name: test-output path: fastlane/test_output diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png deleted file mode 100644 index 602235eaf5..0000000000 --- a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c935c6529a9f9a63915c3cab80dc9fc7df8723db6258c4d8c445df7c84296e65 -size 110159 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png deleted file mode 100644 index ec57afe2dc..0000000000 --- a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ebec20c376958c8a4b10a4055f15963a27ed744e0ac594aae803b0e56c6477a2 -size 108424 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png deleted file mode 100644 index 55ef75591a..0000000000 --- a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f84bcc4acb59ef1a6fb5893b0840b32e3011e6a1e66004b65650ab30321b7f8 -size 97748 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png deleted file mode 100644 index ef91578a53..0000000000 --- a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6b2f89b01650704e45b0c9a57c67f7fbe4cf583299b6d0392b4d79c22725a3f7 -size 132101 From d05c5e614ef24db25e14f8571628ba1ba7545c30 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 14:31:57 +0200 Subject: [PATCH 10/13] recommit --- ...eItemStyler.Bubbles-LTR-with-different-layout-languages.png | 3 +++ ...eItemStyler.Bubbles-RTL-with-different-layout-languages.png | 3 +++ .../PreviewTests/test_timelineItemStyler.Bubbles.png | 3 +++ .../PreviewTests/test_timelineItemStyler.Plain.png | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png create mode 100644 UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png new file mode 100644 index 0000000000..602235eaf5 --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-LTR-with-different-layout-languages.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c935c6529a9f9a63915c3cab80dc9fc7df8723db6258c4d8c445df7c84296e65 +size 110159 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png new file mode 100644 index 0000000000..ec57afe2dc --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles-RTL-with-different-layout-languages.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ebec20c376958c8a4b10a4055f15963a27ed744e0ac594aae803b0e56c6477a2 +size 108424 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png new file mode 100644 index 0000000000..55ef75591a --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Bubbles.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f84bcc4acb59ef1a6fb5893b0840b32e3011e6a1e66004b65650ab30321b7f8 +size 97748 diff --git a/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png new file mode 100644 index 0000000000..ef91578a53 --- /dev/null +++ b/UnitTests/Sources/__Snapshots__/PreviewTests/test_timelineItemStyler.Plain.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b2f89b01650704e45b0c9a57c67f7fbe4cf583299b6d0392b4d79c22725a3f7 +size 132101 From 5587ad0def51c4c69ae41d42877a695eadabd2cb Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 15:45:34 +0200 Subject: [PATCH 11/13] perceptual precision lowered --- Tools/Prefire/PreviewTests.stencil | 2 +- UnitTests/Sources/PreviewTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/Prefire/PreviewTests.stencil b/Tools/Prefire/PreviewTests.stencil index 086eb13180..a5af8fe556 100644 --- a/Tools/Prefire/PreviewTests.stencil +++ b/Tools/Prefire/PreviewTests.stencil @@ -165,7 +165,7 @@ private extension Snapshotting where Value: SwiftUI.View, Format == UIImage { private extension Diffing where Value == UIImage { static func prefireImage(precision: @escaping () -> Float, scale: CGFloat?) -> Diffing { - lazy var originalDiffing = Diffing.image(precision: precision(), scale: scale) + lazy var originalDiffing = Diffing.image(precision: precision(), perceptualPrecision: 0.98, scale: scale) return Diffing( toData: { originalDiffing.toData($0) }, fromData: { originalDiffing.fromData($0) }, diff --git a/UnitTests/Sources/PreviewTests.swift b/UnitTests/Sources/PreviewTests.swift index d5ff971500..1cd5e5c828 100644 --- a/UnitTests/Sources/PreviewTests.swift +++ b/UnitTests/Sources/PreviewTests.swift @@ -158,7 +158,7 @@ private extension Snapshotting where Value: SwiftUI.View, Format == UIImage { private extension Diffing where Value == UIImage { static func prefireImage(precision: @escaping () -> Float, scale: CGFloat?) -> Diffing { - lazy var originalDiffing = Diffing.image(precision: precision(), scale: scale) + lazy var originalDiffing = Diffing.image(precision: precision(), perceptualPrecision: 0.98, scale: scale) return Diffing( toData: { originalDiffing.toData($0) }, fromData: { originalDiffing.fromData($0) }, From b498e69886d65b10901db5f3251002e64a2fc629 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 17:31:26 +0200 Subject: [PATCH 12/13] updated snapshot testing and selected also iOS version --- ElementX.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 13 +++++++++++-- fastlane/Fastfile | 2 +- project.yml | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 65f276241f..3e3daeb7ae 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -5837,7 +5837,7 @@ repositoryURL = "https://github.com/pointfreeco/swift-snapshot-testing"; requirement = { kind = upToNextMinorVersion; - minimumVersion = 1.11.0; + minimumVersion = 1.13.0; }; }; EC6D0C817B1C21D9D096505A /* XCRemoteSwiftPackageReference "Version" */ = { diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index c2e2668b3b..d0555a20be 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -210,8 +210,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-snapshot-testing", "state" : { - "revision" : "dc46eeb3928a75390651fac6c1ef7f93ad59a73b", - "version" : "1.11.1" + "revision" : "696b86a6d151578bca7c1a2a3ed419a5f834d40f", + "version" : "1.13.0" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-syntax.git", + "state" : { + "revision" : "74203046135342e4a4a627476dd6caf8b28fe11b", + "version" : "509.0.0" } }, { diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 4f63335ae0..f13ba2d0db 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -77,7 +77,7 @@ end lane :unit_tests do run_tests( scheme: "UnitTests", - devices: ["iPhone 14"], + device: 'iPhone 14 (16.4)', ensure_devices_found: true, result_bundle: true, number_of_retries: 3, diff --git a/project.yml b/project.yml index 9a832e4640..bc2fc7ce3d 100644 --- a/project.yml +++ b/project.yml @@ -102,7 +102,7 @@ packages: minorVersion: 8.6.0 SnapshotTesting: url: https://github.com/pointfreeco/swift-snapshot-testing - minorVersion: 1.11.0 + minorVersion: 1.13.0 SwiftState: url: https://github.com/ReactKit/SwiftState minorVersion: 6.0.0 From 5d6355fc11a19b912c23c37aae1f773adec21665 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Tue, 19 Sep 2023 18:04:01 +0200 Subject: [PATCH 13/13] added ios version control --- .prefire.yml | 1 + Tools/Prefire/PreviewTests.stencil | 6 ++++++ UnitTests/Sources/PreviewTests.swift | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/.prefire.yml b/.prefire.yml index 7a57aae92f..451f66e0b3 100644 --- a/.prefire.yml +++ b/.prefire.yml @@ -2,3 +2,4 @@ test_configuration: - test_file_path: UnitTests/Sources/PreviewTests.swift - template_file_path: Tools/Prefire/PreviewTests.stencil - simulator_device: "iPhone14" + - required_os: 16 diff --git a/Tools/Prefire/PreviewTests.stencil b/Tools/Prefire/PreviewTests.stencil index a5af8fe556..3f5395041c 100644 --- a/Tools/Prefire/PreviewTests.stencil +++ b/Tools/Prefire/PreviewTests.stencil @@ -16,6 +16,7 @@ import Prefire class PreviewTests: XCTestCase { private let deviceConfig: ViewImageConfig = .iPhoneX private let simulatorDevice = "{{ argument.simulatorDevice|default:"iPhone15,2" }}" + private let requiredOSVersion = {{ argument.simulatorOSVersion|default:"16" }} {% if argument.file %} private var file: StaticString { .init(stringLiteral: "{{ argument.file }}") } @@ -77,9 +78,14 @@ class PreviewTests: XCTestCase { /// Check environments to avoid problems with snapshots on different devices or OS. private func checkEnvironments() { let deviceModel = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] + let osVersion = ProcessInfo().operatingSystemVersion guard deviceModel?.contains(simulatorDevice) ?? false else { fatalError("Switch to using \(simulatorDevice) for these tests.") } + + guard osVersion.majorVersion == requiredOSVersion else { + fatalError("Switch to iOS \(requiredOSVersion) for these tests.") + } } } diff --git a/UnitTests/Sources/PreviewTests.swift b/UnitTests/Sources/PreviewTests.swift index 1cd5e5c828..72368c792f 100644 --- a/UnitTests/Sources/PreviewTests.swift +++ b/UnitTests/Sources/PreviewTests.swift @@ -17,6 +17,7 @@ import Prefire class PreviewTests: XCTestCase { private let deviceConfig: ViewImageConfig = .iPhoneX private let simulatorDevice = "iPhone14" + private let requiredOSVersion = 16 override func setUp() { super.setUp() @@ -70,9 +71,13 @@ class PreviewTests: XCTestCase { /// Check environments to avoid problems with snapshots on different devices or OS. private func checkEnvironments() { let deviceModel = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] + let osVersion = ProcessInfo().operatingSystemVersion guard deviceModel?.contains(simulatorDevice) ?? false else { fatalError("Switch to using \(simulatorDevice) for these tests.") } + guard osVersion.majorVersion == requiredOSVersion else { + fatalError("Switch to iOS \(requiredOSVersion) for these tests.") + } } }