Roborazzi Versions Save

Make JVM Android integration test visible 🤖📸

1.13.0

3 weeks ago

Add experimental, minimal support for iOS in Compose Multiplatform

Roborazzi has supported Compose Desktop, but we hadn't yet supported iOS, which could be a major use case for Compose Multiplatform. Therefore, I have added support for iOS. Now, you can record, compare, and verify just as you would with Android support. https://takahirom.github.io/roborazzi/compose-multiplatform.html#experimental-feature-ios-support

ios_button_compare

However, Roborazzi is fundamentally based on the JVM. Currently, we offer only minimal features. If you are interested in helping to improve these features, please take a look at these issues: https://github.com/takahirom/roborazzi/issues/302 https://github.com/takahirom/roborazzi/issues/305

Changes Affecting Existing Support

To support iOS, we have made some dependency changes for Android and Compose Desktop. I believe these changes will not affect existing behavior. However, if you notice anything, please let me know.

All Kotlin: 1.8.22 -> 1.9.21

dropbox/differ: 0.0.1 -> 0.0.2

Desktop Compose Version

Compose Multiplatform: 1.4.3 -> 1.6.1

What's Changed

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.12.0...1.13.0

1.12.0

1 month ago

Bug Fixes

  • Fixed an issue where recorded images with a transparent background and a scaling option (e.g., 0.5F) were always detected as changes. Thanks for reporting this, @yongsuk44!
  • Addressed a bug related to robolectric.screenshot.hwrdr.native introduced in Robolectric 4.12, which caused unwanted shadows when using Compose's roboCaptureImage{} with this new option. This has now been corrected by @lukas-mercari. Thanks for your contribution!

What's Changed

New Contributors

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.11.0...1.12.0

1.11.0

1 month ago

New feature

In Roborazzi, if you specify outputDir in the Gradle settings, you can use the build cache. Now, Roborazzi passes the setting into the test.

build.gradle

roborazzi {
    outputDir = "src/your/screenshot/folder"
}

gradle.propeties

roborazzi.record.filePathStrategy=relativePathFromRoborazziContextOutputDirectory 

Test

captureRoboImage()
-> saved src/your/screenshot/folder/package.class.method.png


captureRoboImage("test.png")

-> saved src/your/screenshot/folder/test.png

What's Changed

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.10.1...1.11.0

1.10.1

2 months ago

Changes from 1.10.0

This release includes a bug fix for a Javascript error that prevented the HTML report from being displayed.

Changes from 1.9.0

New experimental feature

Custom context data for images and reports

Custom context data enables the addition of information to images and reports in Roborazzi's tests, which I believe is very important. For example, it can include the test class name of a screenshot or whether it is in dark mode. You can now add custom context data using RoborazziOptions, and Roborazzi will add the test class name metadata if you use RoborazziRule. If you have any opinions about this feature, please let me know at https://github.com/takahirom/roborazzi/issues/257. Furthermore, this opens up possibilities with AI. Given that AI now possesses multimodal capabilities, it has become feasible for AI to process images. This feature was made possible thanks to @sanao1006 's contribution of migrating from org.json to gson.

    onView(ViewMatchers.isRoot())
      .captureRoboImage(
        roborazziOptions = RoborazziOptions(
          contextData = mapOf(
            "context_data_key" to "context_data_value"
          )
        )
      )
  }
image

Important bug fix

Gradle attempts to load the test cache whenever possible, but there was an issue where Roborazzi couldn't restore images from the cache. This release includes a fix for this problem. Thank you, @francescocervone, for reporting this issue.

What's Changed

New Contributors

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.9.0...1.10.0

1.10.0

2 months ago

New experimental feature

Custom context data for images and reports

Custom context data enables the addition of information to images and reports in Roborazzi's tests, which I believe is very important. For example, it can include the test class name of a screenshot or whether it is in dark mode. You can now add custom context data using RoborazziOptions, and Roborazzi will add the test class name metadata if you use RoborazziRule. If you have any opinions about this feature, please let me know at https://github.com/takahirom/roborazzi/issues/257. Furthermore, this opens up possibilities with AI. Given that AI now possesses multimodal capabilities, it has become feasible for AI to process images. This feature was made possible thanks to @sanao1006 's contribution of migrating from org.json to gson.

    onView(ViewMatchers.isRoot())
      .captureRoboImage(
        roborazziOptions = RoborazziOptions(
          contextData = mapOf(
            "context_data_key" to "context_data_value"
          )
        )
      )
  }
image

Important bug fix

Gradle attempts to load the test cache whenever possible, but there was an issue where Roborazzi couldn't restore images from the cache. This release includes a fix for this problem. Thank you, @francescocervone, for reporting this issue.

What's Changed

New Contributors

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.9.0...1.10.0

1.9.0

3 months ago

Announcement: Simplified Release Strategy for Roborazzi

We're making some changes to our release strategy to enhance your experience. Moving forward, we will be streamlining our versioning system. Instead of maintaining separate alpha/rc/stable versions, we will integrate experimental features directly into stable releases, marked with clear experimental annotations. This approach aims to simplify updates and improve clarity while ensuring you still have access to the latest features and improvements.

We value your input and experience. If you have any thoughts or feedback on this change, please feel free to share them with us on GitHub Issue #243.

New Experimental Features

  • Introduction of captureScreenRoboImage() Function: This function executes screenshot tests that include dialogs on the screen, offering an alternative to the conventional use of Espresso's ViewInteraction or Compose Test's SemanticsNodeInteraction captureRoboImage(). Thank you, @nelletto, for bringing this issue with dialog screenshots to our attention.

    Before:

    onRoot().captureRoboImage()
    onView(isRoot()).captureRoboImage()
    

    After:

    captureScreenRoboImage()
    
image
  • RoborazziTaskType Property: I developed Roborazzi to facilitate layout viewing during UI tests, addressing the limitations in Robolectric's layout visibility. Initially, Roborazzi couldn't support just viewing layouts during the verification task (roborazziVerifyDebug). Hence, I've introduced a feature allowing task type alteration during test executions.

    onView(ViewMatchers.isRoot())
      .captureRoboImage(
        roborazziOptions = RoborazziOptions(
          taskType = roborazziSystemPropertyTaskType().convertVerifyingToComparing()
        )
      )
    

Behavior Changes

  • Adjustments for Upcoming Robolectric Shadow Rendering Support: While Robolectric is in the process of introducing technical support for shadow rendering, Roborazzi is adapting its screenshot capture method accordingly. We're shifting towards using the PixelCopy class more extensively instead of relying solely on the View draw method. If you notice any issues with this change, please report them to us. Thank you, @sergio-sastre, for highlighting the advantages of using PixelCopy.

Bug Fixes

  • Fixed Potential Memory Leak: Addressed a memory leak issue occurring when using compose captureRoboImage{} multiple times within a single test. (Thanks for reporting this @vetoketju )
  • Resolved File Path Duplication: Corrected an issue where not specifying a file path with relativePathFromRoborazziContextOutputDirectory resulted in duplicated file paths, like build/output/roborazzi/build/output/roborazzi/xxxx.png.
  • Fixed a bug in window ordering for screenshots: Windows are now accurately layered by type for more reliable and consistent screenshot results.
  • Fixed the issue where captureScreenRoboImage() failed to capture Material3 Compose dialogs and bottom sheets. @marianeum Thank you for reporting this issue!
  • Resolved the issue causing comparison images to enlarge when using the scale option.

Others

  • Documentation Enhancement: Added comprehensive documentation using Writerside, a documentation tool from JetBrains. Roborazzi Documentation Thank you, @timothyfroehlich, @sergio-sastre, and @ZacSweers, for your suggestions regarding documentation tools.

  • Thanks to @itochan's contribution, Roborazzi has moved to a version catalog, reduced unwanted dependencies and organized

  • Enhanced performance.

  • Fix Bug Causing Comparison Image to Enlarge and Enhance Performance by Avoiding Creation of Unnecessary Canvases

  • Use ComposeTestRule interface instead of concrete AndroidComposeTestRule class by @GisoBartels in https://github.com/takahirom/roborazzi/pull/241

  • Pass the default output directory setting from Gradle

What's Changed

New Contributors

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.8.0...1.9.0

1.8.0

3 months ago

Announcement: Simplified Release Strategy for Roborazzi

We're making some changes to our release strategy to enhance your experience. Moving forward, we will be streamlining our versioning system. Instead of maintaining separate alpha/rc/stable versions, we will integrate experimental features directly into stable releases, marked with clear experimental annotations. This approach aims to simplify updates and improve clarity while ensuring you still have access to the latest features and improvements.

We value your input and experience. If you have any thoughts or feedback on this change, please feel free to share them with us on GitHub Issue #243.

Fix from 1.8.0-rc-1

New Feature from 1.7

Introducing the experimental roboOutputName() function

Streamline the customization of Roborazzi image file names. This utility is especially effective in parameterized tests, allowing for dynamic file naming based on test parameters. For an example of its usage, see the snippet below, which demonstrates generating screenshots before and after UI interactions.

@Test
fun launchScreen() {
  // Generates a file named "org.your.pkg.TestClassName.launchScreen_before.png"
  onView(ViewMatchers.isRoot()).captureRoboImage("${roboOutputName()}_before.png")
  // Replace with specific actions, e.g., onView(xxx).performClick()
  
  // Generates a file named "org.your.pkg.TestClassName.launchScreen_after.png"
  onView(ViewMatchers.isRoot()).captureRoboImage("${roboOutputName()}_after.png")
}

Tailor your file naming convention in gradle.properties for even more control, such as omitting the package name. Set roborazzi.record.namingStrategy=testClassAndMethod for a streamlined naming pattern. Learn more: Roborazzi Documentation

Enhanced Comparison with Grid and Labels 🚀

This update introduces a new grid and label feature, making visual comparisons more intuitive and effective. The grid layout provides a structured view, while labels offer clear identification, streamlining the testing process.

You can use the old style by setting ComparisonStyle to ComparisonStyle.Simple in RoborazziOptions

  data class CompareOptions(
...
    val comparisonStyle: ComparisonStyle = ComparisonStyle.Grid(),
  ) {
    @ExperimentalRoborazziApi
    sealed interface ComparisonStyle {
      @ExperimentalRoborazziApi
      data class Grid(
        val bigLineSpaceDp: Int? = 16,
        val smallLineSpaceDp: Int? = 4,
        val hasLabel: Boolean = true
      ) : ComparisonStyle

      object Simple : ComparisonStyle
    }

image

Make Roborazzi's ImageComparator customizable.

You can now modify the ImageComparator using CompareOptions.imageComparator.

Behavior changes 🔧

Set the default value of CompareOptions.changeThreshold to zero. This means it will detect even a single pixel change.

What's Changed

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.7.0...1.8.0

1.8.0-rc-2

4 months ago

Fix from 1.8.0-rc-1

New Feature from 1.7

Introducing the experimental roboOutputName() function

Streamline the customization of Roborazzi image file names. This utility is especially effective in parameterized tests, allowing for dynamic file naming based on test parameters. For an example of its usage, see the snippet below, which demonstrates generating screenshots before and after UI interactions.

@Test
fun launchScreen() {
  // Generates a file named "org.your.pkg.TestClassName.launchScreen_before.png"
  onView(ViewMatchers.isRoot()).captureRoboImage("${roboOutputName()}_before.png")
  // Replace with specific actions, e.g., onView(xxx).performClick()
  
  // Generates a file named "org.your.pkg.TestClassName.launchScreen_after.png"
  onView(ViewMatchers.isRoot()).captureRoboImage("${roboOutputName()}_after.png")
}

Tailor your file naming convention in gradle.properties for even more control, such as omitting the package name. Set roborazzi.record.namingStrategy=testClassAndMethod for a streamlined naming pattern. Learn more: Roborazzi Documentation

Enhanced Comparison with Grid and Labels 🚀

This update introduces a new grid and label feature, making visual comparisons more intuitive and effective. The grid layout provides a structured view, while labels offer clear identification, streamlining the testing process.

You can use the old style by setting ComparisonStyle to ComparisonStyle.Simple in RoborazziOptions

  data class CompareOptions(
...
    val comparisonStyle: ComparisonStyle = ComparisonStyle.Grid(),
  ) {
    @ExperimentalRoborazziApi
    sealed interface ComparisonStyle {
      @ExperimentalRoborazziApi
      data class Grid(
        val bigLineSpaceDp: Int? = 16,
        val smallLineSpaceDp: Int? = 4,
        val hasLabel: Boolean = true
      ) : ComparisonStyle

      object Simple : ComparisonStyle
    }

image

Make Roborazzi's ImageComparator customizable.

You can now modify the ImageComparator using CompareOptions.imageComparator.

Behavior changes 🔧

Set the default value of CompareOptions.changeThreshold to zero. This means it will detect even a single pixel change.

What's Changed

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.7.0...1.8.0-rc-1

1.9.0-alpha-4

4 months ago

Bug Fixes and Improvements

  • Fixed the issue where captureScreenRoboImage() failed to capture Material3 Compose dialogs and bottom sheets. @marianeum Thank you for reporting this issue!
  • Resolved the issue causing comparison images to enlarge when using the scale option.
  • Enhanced performance.

What's Changed

New Contributors

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.9.0-alpha-3...1.9.0-alpha-4

1.9.0-alpha-3

4 months ago

Thanks to @itochan's contribution, Roborazzi has moved to a version catalog, reduced unwanted dependencies and organized

What's Changed

New Contributors

Full Changelog: https://github.com/takahirom/roborazzi/compare/1.9.0-alpha-2...1.9.0-alpha-3