swift-snapshot-testing
swift-snapshot-testing copied to clipboard
feat(macOS): deterministically snapshot `NSView`s on any device
Deterministically snapshot NSView
s on any device
Summary
This PR builds upon #412 but maintains compatibility with existing API-behaviour. Additionally to fixing backingScaleFactor
issues, it also fixes the color space issues discussed in #477. Therefore all relevant rendering parameters can be set in a deterministic way allowing macOS snapshot test to run on any device including CI.
In Detail
As far as I can tell from experimenting, the rendering of NSView
is determined by its .size
, .appearance
.window.backingScaleFactor
, and window.colorSpace
. This PR tackles the later two and adds a GenericWindow
subclass of NSWindow
which can be configured with a specific backingScaleFactor
and colorSpace
. The .image
snapshot strategy on NSView
is extended to allow the caller to optionally set a specific NSAppearance
and to render the view in a GenericWindow
. This window can be configure to use CI compatible values (eg. backingScaleFactor: 1.0
and colorSpace: .genericRGB
). There is even a handy preconfigured static instance GenericWindow.ci
.
Added Tests
Two tests are added to showcase the CI-compatibility. These are the CI-compatible version of pre-existing macOS NSView tests:
-
testNSViewCICompatible
-
testNSViewWithLayerCICompatible
For passing tests see https://github.com/tillhainbach/swift-snapshot-testing/pull/3
Caveats/Gotchas
The current implementation for .image
for NSView
has side-effect on the view which are not undone. This means that the calling order for .image
and .recursiveDescription
strategy matters. I added a note to the doc comment.
Minor Fixes along the way
I noticed some test failures on my local machine that where:
- related to light/dark mode setting on test machine. I refactor the failing tests to explicitly use
.aqua
(light mode) appearance (the one used for provided target snapshot) - related to number formatting using localised formatting (decimal separator in my case). I changed the number formatter to use the a
.
as the decimal separator.
Other
This PR adds an additional step to the GitHub actions which uploads any failing snapshot artefacts. This is great for debugging failures on CI.
Related PRs and Issues
- closes #412
- fixes issues with #477. Supporting SwiftUI, however, could be simplified to just pullback to NSView.
- closes #428
- closes #313
- closes #305
PS: I left the WIP and intermediate commits to improve comprehensibility for review but will squash them once this PR is approved to reduce the noise.
What's the state of this? Is there any plan to getting this merged? Looks like there's no SwiftUI support on macOS yet. With Apple getting serious with SwiftUI on macOS now with Ventura (the new Settings app was written with SwiftUI it looks like), I'd love to see proper support for SwiftUI in this lib as well. Are there any blockers right now?
Are there any plans to get this merged?
For anyone finding and needing this before it is merged, I created a branch in fork which basically combines this PR as well as #477: https://github.com/Obbut/swift-snapshot-testing/tree/updated-swiftui-macos
If the comments from @stephencelis are blocking to get this merged, I'd be happy to create a new PR with that feedback implemented
If the comments from @stephencelis are blocking to get this merged, I'd be happy to create a new PR with that feedback implemented
Would be great if you can take over. I was wanting to address this but I can't find the time since I haven't been working on anything swift related 🥲.
@Obbut Did you ever get the time to look at this? These look like great changes