Skip to content

Releases: takahirom/roborazzi

1.11.0

18 Mar 02:22
08af633
Compare
Choose a tag to compare

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

  • Add helpful error message for class cast exception by @takahirom in #267
  • Use 'verify' task when specifying both 'compare' and 'verify' by @takahirom in #269
  • Respect gradle build dir for reports by @takahirom in #270
  • Add "The images taken from Roborazzi seem broken" FAQ by @takahirom in #277

Full Changelog: 1.10.1...1.11.0

1.10.1

18 Feb 08:01
bd23cf7
Compare
Choose a tag to compare

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 #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: 1.9.0...1.10.0

1.10.0

18 Feb 02:23
4a90856
Compare
Choose a tag to compare

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 #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: 1.9.0...1.10.0

1.9.0

26 Jan 09:28
89c2286
Compare
Choose a tag to compare

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 #241

  • Pass the default output directory setting from Gradle

What's Changed

New Contributors

Full Changelog: 1.8.0...1.9.0

1.8.0

22 Jan 01:27
17046b8
Compare
Choose a tag to compare

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

  • Use ComposeTestRule interface instead of concrete AndroidComposeTestRule class.
    @GisoBartels, Thank you for your code contribution!
    #241

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

  • Make Roborazzi's ImageComparator customizable by @takahirom in #182
  • Set Default Value of CompareOptions.changeThreshold to Zero by @takahirom in #183
  • Fixed a bug where options set via RoborazziRule were ignored by @takahirom in #187
  • Fix the issue of keeping the previous test reports by @takahirom in #189
  • [CI]Speed up integration tests by @takahirom in #190
  • Refactor processOutputImageAndReport by @takahirom in #191
  • Fix the bug where the test reports are not updated when the tests fail by @takahirom in #194
  • Add a document about experimental output parameter by @takahirom in #195
  • Migrate Robolectric to gradle version catalog by @takahirom in #196
  • Add default parameter for CompareOptions.resultValidator by @takahirom in #203
  • Enhance Flexibility with Custom File Naming in Roborazzi via roboOutputName() Function by @takahirom in #205
  • Fix the issue where errors are ignored and occur when changing the size during GIF recording. by @takahirom in #210
  • Add labels and grid lines for the comparison image by @takahirom in #206
  • Fix simple comparison image by @takahirom in #213

Full Changelog: 1.7.0...1.8.0

1.8.0-rc-2

09 Jan 12:02
96d1840
Compare
Choose a tag to compare

Fix from 1.8.0-rc-1

  • Use ComposeTestRule interface instead of concrete AndroidComposeTestRule class.
    @GisoBartels, Thank you for your code contribution!
    #241

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

  • Make Roborazzi's ImageComparator customizable by @takahirom in #182
  • Set Default Value of CompareOptions.changeThreshold to Zero by @takahirom in #183
  • Fixed a bug where options set via RoborazziRule were ignored by @takahirom in #187
  • Fix the issue of keeping the previous test reports by @takahirom in #189
  • [CI]Speed up integration tests by @takahirom in #190
  • Refactor processOutputImageAndReport by @takahirom in #191
  • Fix the bug where the test reports are not updated when the tests fail by @takahirom in #194
  • Add a document about experimental output parameter by @takahirom in #195
  • Migrate Robolectric to gradle version catalog by @takahirom in #196
  • Add default parameter for CompareOptions.resultValidator by @takahirom in #203
  • Enhance Flexibility with Custom File Naming in Roborazzi via roboOutputName() Function by @takahirom in #205
  • Fix the issue where errors are ignored and occur when changing the size during GIF recording. by @takahirom in #210
  • Add labels and grid lines for the comparison image by @takahirom in #206
  • Fix simple comparison image by @takahirom in #213

Full Changelog: 1.7.0...1.8.0-rc-1

1.9.0-alpha-4

04 Jan 12:49
4682c77
Compare
Choose a tag to compare

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

  • Fix CaptureResultTest and Add plan test workflow by @momomomo111 in #238
    @momomomo111, thank you for informing me about the broken tests and code contribution!
  • Use View draw method to capture for Compose Material3 by @takahirom in #237
  • Fix Bug Causing Comparison Image to Enlarge and Enhance Performance by Avoiding Creation of Unnecessary Canvases by @takahirom in #239

New Contributors

Full Changelog: 1.9.0-alpha-3...1.9.0-alpha-4

1.9.0-alpha-3

01 Jan 03:52
dd50168
Compare
Choose a tag to compare

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

What's Changed

  • Migrate to version catalog by @itochan in #231
    @itochan, thank you for your contribution! It really helps to make our development process smoother.
    @timothyfroehlich, thank you for your review!
  • Update dropbox differ and remove bom dependency and remove unneeded junit dependency by @takahirom in #234

New Contributors

Full Changelog: 1.9.0-alpha-2...1.9.0-alpha-3

1.9.0-alpha-2

01 Jan 03:51
5e429cc
Compare
Choose a tag to compare

Bugfix

Fixed a bug in window ordering for screenshots: Windows are now accurately layered by type for more reliable and consistent screenshot results.

What's Changed

Full Changelog: 1.9.0-alpha-1...1.9.0-alpha-2

1.9.0-alpha-1

17 Dec 04:27
def2a46
Compare
Choose a tag to compare

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.

Others

What's Changed

Full Changelog: 1.8.0-rc-1...1.9.0-alpha-1