pointfreeco / swift-snapshot-testing

đŸ“¸ Delightful Swift snapshot testing.
https://www.pointfree.co/episodes/ep41-a-tour-of-snapshot-testing
MIT License
3.75k stars 574 forks source link

Can not snasphot inserted Sublayer #359

Open billypchan opened 4 years ago

billypchan commented 4 years ago

Hi! When I rewrite one of my snapshot written with FBSnapshotTestCase, I find that the snapshot does not have the layer I added to an image view, but the old version of the snapshot (https://github.com/wireapp/wire-ios/pull/4439/commits/081a79094ee4c7fb6ce31411274b647376ea82da?short_path=68c0408#diff-68c04082c71cf5bdf8e48e5cf4a64110) has it:

I add the layer in this way:

let layer = CALayer()
layer.backgroundColor = UIColor.black.cgColor
imageView?.layer.insertSublayer(layer, at: 0)

And I snapshot the view controller:

verifySnapshot(matching: viewcontroller,
                                     as: .image)

The snapshot reference image do not have the black layer added.

Any suggestions for this case? Thanks in advance!

darknoon commented 4 years ago

Does the layer have a non-zero frame? Seems like there is some relevant code missing here.

billypchan commented 4 years ago

I check that the frame of the layer is set. see https://github.com/wireapp/wire-ios/blob/b331ea4b06652d01f9298b553d91e6818d41782a/Wire-iOS/Sources/UserInterface/Components/Controllers/FullscreenImageViewController.swift#L525

billypchan commented 4 years ago

And I also found that the blur layer can not be snapshotted, maybe also related to layer?

darknoon commented 4 years ago

@billypchan Yes, the way that snapshots are taken is not great… blur in general is not implemented in CoreGraphics drawing and because CA is composited in another process it is not easy to get a snapshot within the App's process that accurately represents the content. You can compare this library to FBSnapshotTestCase and they are pretty similar.

When Apple frameworks like SceneKit need to render within the current process they use an API called CARenderer, which is public API on macOS but not on iOS (nonetheless, it does exist).

AFAICT APIs like snapshotView(afterScreenUpdates:) use a placeholder that CA can use to duplicate the content.