From 5353f8fd8d90002fc1d347ae747a0394b77965fb Mon Sep 17 00:00:00 2001 From: Noah Martin Date: Fri, 14 Nov 2025 08:29:12 -0800 Subject: [PATCH] Support new a11y snapshot API --- ios/HackerNews.xcodeproj/project.pbxproj | 43 ++++++++++++++++--- .../xcshareddata/swiftpm/Package.resolved | 23 +++++++--- .../HackerNewsSnapshotTest.swift | 39 +++++++++++++++++ 3 files changed, 92 insertions(+), 13 deletions(-) diff --git a/ios/HackerNews.xcodeproj/project.pbxproj b/ios/HackerNews.xcodeproj/project.pbxproj index 070b71d6..bb96f7e0 100644 --- a/ios/HackerNews.xcodeproj/project.pbxproj +++ b/ios/HackerNews.xcodeproj/project.pbxproj @@ -34,6 +34,8 @@ F48E9DA82D4D2A3C00FD8B30 /* Common in Embed Frameworks */ = {isa = PBXBuildFile; productRef = F48E9DA62D4D2A3C00FD8B30 /* Common */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; F48E9ECB2D4D691600FD8B30 /* ETDistribution in Frameworks */ = {isa = PBXBuildFile; productRef = F48E9ECA2D4D691600FD8B30 /* ETDistribution */; }; F48E9FDB2D51690400FD8B30 /* ETDistribution in Embed Frameworks */ = {isa = PBXBuildFile; productRef = F48E9ECA2D4D691600FD8B30 /* ETDistribution */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + FA80C2702EC78D7500A700AB /* AccessibilitySnapshotCore in Frameworks */ = {isa = PBXBuildFile; productRef = FA80C26F2EC78D7500A700AB /* AccessibilitySnapshotCore */; }; + FA80C2732EC78F2D00A700AB /* AccessibilitySnapshotCore in Frameworks */ = {isa = PBXBuildFile; productRef = FA80C2722EC78F2D00A700AB /* AccessibilitySnapshotCore */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -203,10 +205,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + FA80C2732EC78F2D00A700AB /* AccessibilitySnapshotCore in Frameworks */, A495A6662CED57BB009A2A6B /* SnapshotTesting in Frameworks */, C3AC6AD92CB6E8F7006BD22D /* SnapshottingTests in Frameworks */, A4BED5C32AD5E083001642B3 /* (null) in Frameworks */, F48E9DA32D4D2A3500FD8B30 /* Common in Frameworks */, + FA80C2702EC78D7500A700AB /* AccessibilitySnapshotCore in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -492,12 +496,13 @@ A47309B22AA29D9600201376 /* XCRemoteSwiftPackageReference "SwiftSoup" */, 995A2BEDEF224F7085D3DB13 /* XCRemoteSwiftPackageReference "sentry-cocoa" */, A495B2932BFEA11B00A8A8A9 /* XCRemoteSwiftPackageReference "Reaper" */, - A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews-iOS" */, + A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews" */, A495A6642CED57BB009A2A6B /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */, F45F6E532D4D1D3E003FA9A3 /* XCLocalSwiftPackageReference "Packages/Common" */, F45F6F4C2D4D2554003FA9A3 /* XCLocalSwiftPackageReference "Packages/Fonts" */, F48E9EC92D4D691600FD8B30 /* XCRemoteSwiftPackageReference "ETDistribution" */, A42271692DE78DEF002F03D5 /* XCRemoteSwiftPackageReference "faultordering" */, + FA80C2712EC78F2D00A700AB /* XCRemoteSwiftPackageReference "AccessibilitySnapshot" */, ); productRefGroup = A427057A2A4293B10057E439 /* Products */; projectDirPath = ""; @@ -1260,9 +1265,9 @@ minimumVersion = 1.6.0; }; }; - A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews-iOS" */ = { + A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/EmergeTools/SnapshotPreviews-iOS"; + repositoryURL = "https://github.com/EmergeTools/SnapshotPreviews"; requirement = { branch = main; kind = branch; @@ -1276,6 +1281,22 @@ minimumVersion = 0.2.1; }; }; + FA80C26E2EC78D7500A700AB /* XCRemoteSwiftPackageReference "AccessibilitySnapshot" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/cashapp/AccessibilitySnapshot.git"; + requirement = { + kind = exactVersion; + version = 1.0.2; + }; + }; + FA80C2712EC78F2D00A700AB /* XCRemoteSwiftPackageReference "AccessibilitySnapshot" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/cashapp/AccessibilitySnapshot"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.10.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -1311,17 +1332,17 @@ }; A4D28AED2C237E2A007F20D0 /* SnapshotPreferences */ = { isa = XCSwiftPackageProductDependency; - package = A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews-iOS" */; + package = A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews" */; productName = SnapshotPreferences; }; A4D28AEF2C237E2A007F20D0 /* SnapshottingTests */ = { isa = XCSwiftPackageProductDependency; - package = A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews-iOS" */; + package = A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews" */; productName = SnapshottingTests; }; C3AC6AD82CB6E8F7006BD22D /* SnapshottingTests */ = { isa = XCSwiftPackageProductDependency; - package = A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews-iOS" */; + package = A4D28AEC2C237E2A007F20D0 /* XCRemoteSwiftPackageReference "SnapshotPreviews" */; productName = SnapshottingTests; }; F40E429F2EA80E1600E53876 /* SentrySwiftUI */ = { @@ -1364,6 +1385,16 @@ package = F48E9EC92D4D691600FD8B30 /* XCRemoteSwiftPackageReference "ETDistribution" */; productName = ETDistribution; }; + FA80C26F2EC78D7500A700AB /* AccessibilitySnapshotCore */ = { + isa = XCSwiftPackageProductDependency; + package = FA80C26E2EC78D7500A700AB /* XCRemoteSwiftPackageReference "AccessibilitySnapshot" */; + productName = AccessibilitySnapshotCore; + }; + FA80C2722EC78F2D00A700AB /* AccessibilitySnapshotCore */ = { + isa = XCSwiftPackageProductDependency; + package = FA80C2712EC78F2D00A700AB /* XCRemoteSwiftPackageReference "AccessibilitySnapshot" */; + productName = AccessibilitySnapshotCore; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = A42705712A4293B10057E439 /* Project object */; diff --git a/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 476735e3..d7c584dc 100644 --- a/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/HackerNews.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "956841bd48445375af9b85d6617a2e4c1144af55323707809f3eef68e28d1ff6", + "originHash" : "41633491f6f1fcb0afdded3559f6bb4f810d305eb9b709a778b41dfa7a3dfa17", "pins" : [ { "identity" : "accessibilitysnapshot", "kind" : "remoteSourceControl", - "location" : "https://github.com/EmergeTools/AccessibilitySnapshot.git", + "location" : "https://github.com/cashapp/AccessibilitySnapshot", "state" : { - "revision" : "54046d8fa44b9fa9f0e2229526f6ed89cb5e0ec2", - "version" : "1.0.2" + "revision" : "8d4bc42c1ba23755147b931e1e94c775df91a997", + "version" : "0.10.0" } }, { @@ -37,6 +37,15 @@ "version" : "0.16.0" } }, + { + "identity" : "ios-snapshot-test-case", + "kind" : "remoteSourceControl", + "location" : "https://github.com/uber/ios-snapshot-test-case.git", + "state" : { + "revision" : "7b10770333a961be6e5a41c9ce04b8c6d3990126", + "version" : "8.0.0" + } + }, { "identity" : "reaper", "kind" : "remoteSourceControl", @@ -64,12 +73,12 @@ } }, { - "identity" : "snapshotpreviews-ios", + "identity" : "snapshotpreviews", "kind" : "remoteSourceControl", - "location" : "https://github.com/EmergeTools/SnapshotPreviews-iOS", + "location" : "https://github.com/EmergeTools/SnapshotPreviews", "state" : { "branch" : "main", - "revision" : "fc7a10d6307076565c5a780ca36dee6cb31fcccd" + "revision" : "1b3bd9bb341de85d927a78ad8874a35d081a8a66" } }, { diff --git a/ios/HackerNewsTests/HackerNewsSnapshotTest.swift b/ios/HackerNewsTests/HackerNewsSnapshotTest.swift index fa9efd58..8ba12653 100644 --- a/ios/HackerNewsTests/HackerNewsSnapshotTest.swift +++ b/ios/HackerNewsTests/HackerNewsSnapshotTest.swift @@ -7,6 +7,12 @@ import Foundation import SnapshottingTests +#if canImport(UIKit) +import UIKit +#endif +#if canImport(AccessibilitySnapshotCore) +import AccessibilitySnapshotCore +#endif class HackerNewsSnapshotTest: SnapshotTest { override class func snapshotPreviews() -> [String]? { @@ -16,4 +22,37 @@ class HackerNewsSnapshotTest: SnapshotTest { override class func excludedSnapshotPreviews() -> [String]? { return nil } + +#if canImport(UIKit) && !os(watchOS) && !os(visionOS) && !os(tvOS) +override open class func setupA11y() -> ((UIViewController, UIWindow, PreviewLayout) -> UIView)? { + return { (controller: UIViewController, window: UIWindow, layout: PreviewLayout) in + let containerVC = controller.parent + let containedView: UIView + switch layout { + case .device: + containedView = containerVC?.view ?? controller.view + default: + containedView = controller.view + } + let a11yView = AccessibilitySnapshotView( + containedView: containedView, + viewRenderingMode: controller.view.bounds.size.requiresCoreAnimationSnapshot ? .renderLayerInContext : .drawHierarchyInRect, + activationPointDisplayMode: .never, + showUserInputLabels: true) + + a11yView.center = window.center + window.addSubview(a11yView) + + _ = try? a11yView.parseAccessibility(useMonochromeSnapshot: false) + a11yView.sizeToFit() + return a11yView + } +} +#endif +} + +extension CGSize { + var requiresCoreAnimationSnapshot: Bool { + height >= UIScreen.main.bounds.size.height * 2 + } }