Skip to content

Commit

Permalink
Merge pull request #5 from takahirom/takahirom/add-toleranceThreshold…
Browse files Browse the repository at this point in the history
…-for-verification/2023-03-23

Add changeThreshold for verification
  • Loading branch information
takahirom authored Mar 23, 2023
2 parents c7ef27e + 110b864 commit 08de620
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 18 deletions.
40 changes: 22 additions & 18 deletions roborazzi/src/main/java/com/github/takahirom/roborazzi/Roborazzi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fun ViewInteraction.captureRoboImage(
// currently, gif compare is not supported
if (!roborazziRecordingEnabled()) return
perform(ImageCaptureViewAction(captureOptions) { canvas ->
saveOrVerify(canvas, file)
saveOrVerify(canvas, file, captureOptions)
canvas.release()
})
}
Expand Down Expand Up @@ -138,7 +138,7 @@ fun SemanticsNodeInteraction.captureRoboImage(
),
captureOptions = captureOptions,
) { canvas ->
saveOrVerify(canvas, file)
saveOrVerify(canvas, file, captureOptions)
canvas.release()
}
}
Expand Down Expand Up @@ -271,13 +271,13 @@ fun ViewInteraction.captureAndroidView(
}
},
saveGif = { file ->
saveGif(file, canvases)
saveGif(file, canvases)
},
saveLastImage = { file ->
saveLastImage(canvases, file)
saveLastImage(canvases, file, captureOptions)
},
saveAllImage = { fileCreator ->
saveAllImage(fileCreator, canvases)
saveAllImage(fileCreator, canvases, captureOptions)
},
clear = {
canvases.forEach { it.release() }
Expand All @@ -288,14 +288,15 @@ fun ViewInteraction.captureAndroidView(

private fun saveLastImage(
canvases: MutableList<RoboCanvas>,
file: File
file: File,
captureOptions: CaptureOptions,
) {
val roboCanvas = canvases.lastOrNull()
if (roboCanvas == null) {
println("Roborazzi could not capture for this test")
return
}
saveOrVerify(roboCanvas, file)
saveOrVerify(roboCanvas, file, captureOptions)
}

// Only for library, please don't use this directly
Expand Down Expand Up @@ -356,10 +357,10 @@ fun SemanticsNodeInteraction.captureComposeNode(
saveGif(file, canvases)
},
saveLastImage = { file ->
saveLastImage(canvases, file)
saveLastImage(canvases, file, captureOptions)
},
saveAllImage = { fileCreator ->
saveAllImage(fileCreator, canvases)
saveAllImage(fileCreator, canvases, captureOptions)
},
clear = {
canvases.forEach { it.release() }
Expand Down Expand Up @@ -389,26 +390,29 @@ private fun saveGif(

private fun saveAllImage(
fileCreator: (String) -> File,
canvases: MutableList<RoboCanvas>
canvases: MutableList<RoboCanvas>,
captureOptions: CaptureOptions,
) {
canvases.forEachIndexed { index, canvas ->
saveOrVerify(canvas, fileCreator(index.toString()))
saveOrVerify(canvas, fileCreator(index.toString()), captureOptions)
}
}

private fun saveOrVerify(canvas: RoboCanvas, file: File) {
private fun saveOrVerify(canvas: RoboCanvas, file: File, captureOptions: CaptureOptions) {
if (roborazziVerifyEnabled()) {
val goldenRoboCanvas = if (file.exists()) {
RoboCanvas.load(file)
} else {
RoboCanvas(canvas.width, canvas.height, true)
}
val changed = if (canvas.height == goldenRoboCanvas.height && canvas.width == goldenRoboCanvas.width) {
val comparisonResult = canvas.differ(goldenRoboCanvas)
comparisonResult.pixelDifferences.toFloat() / comparisonResult.pixelCount > 0.01
} else {
true
}
val changed =
if (canvas.height == goldenRoboCanvas.height && canvas.width == goldenRoboCanvas.width) {
val comparisonResult = canvas.differ(goldenRoboCanvas)
val changeRatio = comparisonResult.pixelDifferences.toFloat() / comparisonResult.pixelCount
changeRatio > captureOptions.verifyOptions.changeThreshold
} else {
true
}
if (changed) {
RoboCanvas.generateCompareCanvas(goldenRoboCanvas, canvas)
.save(File(file.parent, file.nameWithoutExtension + "_compare." + file.extension))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ internal fun isNativeGraphicsEnabled() = try {

class CaptureOptions(
val captureType: CaptureType = if (isNativeGraphicsEnabled()) CaptureType.Screenshot() else CaptureType.Dump(),
val verifyOptions: VerifyOptions = VerifyOptions()
) {
sealed interface CaptureType {
class Screenshot : CaptureType
Expand All @@ -197,6 +198,14 @@ class CaptureOptions(
) : CaptureType
}

data class VerifyOptions(
/**
* This value determines the threshold of pixel change at which the diff image is output or not.
* The value should be between 0 and 1
*/
val changeThreshold: Double = 0.1
)

internal val shouldTakeBitmap: Boolean = when (captureType) {
is CaptureType.Dump -> {
if (captureType.takeScreenShot && !isNativeGraphicsEnabled()) {
Expand Down

0 comments on commit 08de620

Please sign in to comment.