Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compose UI testing - How do I assert a text color?

I'm trying to test a Text that on my component I can print it in different colors, so on my test I'm verifying it gets the expected color. I was looking for a method to return the color but I did not find any.

From now I'm asserting that the text is correct and the visibility is correct, but when trying to find the method to get the colour I get too deep and I'm looking for a simpler solution.

composeTestRule.onNode(hasTestTag("testTagForButton"), true)
            .assertExists()
            .assertTextEquals("Testing")

I've check that I can do something like .fetchSemanticsNode().layoutInfo.getModifierInfo() to get into the Modifier and perhaps from there I can get the colour, but it's too much maybe. Also I've found this .captureToImage() that perhaps I could get the colour on it, but since I had to put the pixels I decided that it's not the way.

Is there any simple way to get that?

like image 244
Skizo-ozᴉʞS Avatar asked Nov 17 '25 12:11

Skizo-ozᴉʞS


2 Answers

I am by no means a compose expert, but just looking at compose source code, you could utilize their GetTextLayoutResult accessibility semantic action. This will contain all the properties that are used to render the Text on a canvas.

Some quick and dirty extension functions I put up for convenience:

fun SemanticsNodeInteraction.assertTextColor(
    color: Color
): SemanticsNodeInteraction = assert(isOfColor(color))

private fun isOfColor(color: Color): SemanticsMatcher = SemanticsMatcher(
    "${SemanticsProperties.Text.name} is of color '$color'"
) {
    val textLayoutResults = mutableListOf<TextLayoutResult>()
    it.config.getOrNull(SemanticsActions.GetTextLayoutResult)
        ?.action
        ?.invoke(textLayoutResults)
    return@SemanticsMatcher if (textLayoutResults.isEmpty()) {
        false
    } else {
        textLayoutResults.first().layoutInput.style.color == color
    }
}

Which can be then used like this:

composeTestRule.onNode(hasTestTag("testTagForButton"), true)
            .assertExists()
            .assertTextEquals("Testing")
            .assertTextColor(Color.Black)
like image 156
romtsn Avatar answered Nov 19 '25 01:11

romtsn


I am unable to comment post above, also didn't find question about checking background color, so decide to place my version here.

private fun hasBackground(node: SemanticsNode, color: Color, shape: Shape): Boolean {
    return node.layoutInfo.getModifierInfo().filter { modifierInfo ->
        modifierInfo.modifier == Modifier.background(color, shape)
    }.size == 1
}

To test background color and don't touch debug inspection info (this isn't for testing) we are unable to test only background color, but can test whole background by comparing production background (which placed into modifier) with our testing one.

Hope it help somebody.

like image 23
Vladislav M Avatar answered Nov 19 '25 03:11

Vladislav M



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!