'SemanticsNodeInteraction.captureToImage() returns slightly different result depending on device/composable

My goal is to test colors of my composables. For some reason assertion below fails on specific device/composable (e.g. Composable1 passes on Device1 and on Emulator1, Composable2 fails on Device1, but passes on Emulator1). The color difference is marginal (e.g. #3F3C34 / #403C34). What might be the cause of this problem? Is there any way to get consistent results, beside allowing slight difference in color's assertion?

internal fun SemanticsNodeInteraction.assertColorAtRelativePositionStrict(
    expected: Color,
    @FloatRange(from = 0.0, to = 1.0) xPercentage: Float,
    @FloatRange(from = 0.0, to = 1.0) yPercentage: Float,
): SemanticsNodeInteraction {
    val bitmap = captureToImage().asAndroidBitmap()
    val x = ((bitmap.width - 1) * xPercentage).roundToInt()
    val y = ((bitmap.height - 1) * yPercentage).roundToInt()
    val capturedColor = bitmap.getColor(x, y)

    assert(capturedColor == expected) {
        "Captured color was ${capturedColor.toArgb().toHexString()} " +
            "but expected ${expected.toArgb().toHexString()}."
    }
    return this
}

private fun Int.toHexString() = String.format("#%06X", (0xFFFFFF and this))

Expected color and color, used in compoasable, are acquired from colors.xml.



Solution 1:[1]

I think this issues happened because different dp / pixel size for each device. I would recommend to create more isolated compose widget to improve test stability.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Devara