pointfreeco / swift-snapshot-testing

📸 Delightful Swift snapshot testing.
https://www.pointfree.co/episodes/ep41-a-tour-of-snapshot-testing
MIT License
3.68k stars 556 forks source link

Use keyboardLayoutGuide #859

Open rubengrill opened 1 month ago

rubengrill commented 1 month ago

When trying to use Keyboard Layout Guide it seems that the keyboard layout is not set (at top with no height) and the resulting screenshot is incorrect therefore. I am aware that for screenshot tests there is no keyboard, but my expectation would have been that the keyboard layout then matches the bottom part below the safe area (in other words keyboard layout top = safe area bottom). This would be in line with what Apple documents:

When the keyboard isn’t onscreen, the guide is at the bottom of the window and has a height equal to the bottom of the current safeAreaInsets.

Example:

class FooVC: UIViewController {

    override func viewDidLoad() {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setTitle("Foobar", for: .normal)
        view.addSubview(button)
        button.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        button.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        button.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        button.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor).isActive = true
    }

}

class FooVCTests: XCTestCase {

    func testFoobar() {
        assertSnapshot(matching: FooVC(), as: .image)
    }

}

It correctly works when replacing the keyboard layout guide:

button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true

How do you use keyboard layout guide in snapshot tests? Is it possible to somehow set the keyboard layout guide in tests? Or are you using the keyboard layout guide differently (maybe always in combination with safe area layout guide)?

rubengrill commented 4 weeks ago

I found out that it does work if a safe area is defined with any non null bottom value.

Works:

assertSnapshot(matching: vc, as: .image(on: .init(safeArea: .init(top: 0, left: 0, bottom: 1, right: 0), size: .init(width: 375, height: 812))))

Does not work:

assertSnapshot(matching: vc, as: .image(on: .init(safeArea: .init(top: 0, left: 0, bottom: 0, right: 0), size: .init(width: 375, height: 812))))

Since all predefined configs have a safe area, this issue should not happen when these are used:

assertSnapshot(matching: vc, as: .image(on: .iPhoneX))