Skip to content

Addition of the delay Parameter in the image for Controlled Delay Snapshot #973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

o-nnerb
Copy link

@o-nnerb o-nnerb commented Apr 11, 2025

Problem Detected

The existing wait method in the SnapshotTesting library is designed to pause test execution for a period before starting snapshot capture. However, this behavior does not allow asynchronous operations (such as animations, ViewModel requests, or UI updates) to complete during the waiting period. This limits critical integration testing scenarios where it is necessary to:

  1. Initiate screen rendering.
  2. Wait for asynchronous processes (e.g., mocked requests) to complete.
  3. Capture the final UI state after updates.

The wait method simply pauses the test before starting, not allowing UI interaction during the waiting period.


Implemented Solution

I added a new delay parameter to the image method to allow snapshot capture to occur after a controlled delay, during which the UI continues to render normally. This:

  • Enables more realistic testing: The UI can process animations, mocked requests, or transitions while the delay is counting.
  • Is backward compatible: The delay parameter is optional (nil by default), preserving existing functionality.
  • Does not require extensive refactoring: The solution was implemented directly in image without altering the library's main structure.

How It Works

  1. Initiates view rendering normally.
  2. Schedules a delay (specified via delay) after rendering begins.
  3. Captures the snapshot only after the delay, ensuring all asynchronous operations have time to update the UI.

Usage Example

// Integration test with mocked request
func testViewModelUpdatesUI() {
    let viewModel = MyViewModel()
    let viewController = MyViewController(viewModel: viewModel)
    
    // Starts the mocked request (asynchronous)
    viewModel.fetchData()
    
    // Waits 1 second for the UI to update after the request
    assertSnapshot(
        matching: viewController,
        as: .image(delay: 1.0) // 1-second delay
    )
}

Benefits

  • More robust tests: Allows validation of dynamic UI states after asynchronous operations.
  • Compatibility with complex use cases: Useful for testing animations, navigation transitions, or data updates.
  • No backward compatibility issues: Maintains default image behavior when delay is not specified.

Difference between wait and delay

Feature wait (Existing) delay (New Contribution)
When the delay occurs Before test initialization. After UI rendering begins.
UI Updates The UI is not rendered during the delay. The UI continues normal rendering.
Ideal Use Wait for synchronous operations before snapshot. Wait for asynchronous operations during snapshot.

Impact on the Library

  • No API Breakage: The delay parameter is optional and preserves the existing image signature.
  • Incremental Improvement: Expands the utility of image for advanced scenarios without altering the library's main logic.

This contribution addresses a critical gap in integration testing and offers additional flexibility to SnapshotTesting users.

@o-nnerb
Copy link
Author

o-nnerb commented Apr 12, 2025

Hello @stephencelis and @mbrandonw,

Would you be able to review this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant