@@ -16,8 +16,11 @@ import androidx.compose.material3.TextField
1616import androidx.compose.ui.Alignment
1717import androidx.compose.ui.Modifier
1818import androidx.compose.ui.platform.testTag
19+ import androidx.compose.ui.semantics.clearAndSetSemantics
20+ import androidx.compose.ui.semantics.editableText
1921import androidx.compose.ui.semantics.invisibleToUser
2022import androidx.compose.ui.semantics.semantics
23+ import androidx.compose.ui.text.AnnotatedString
2124import androidx.compose.ui.text.input.TextFieldValue
2225import androidx.compose.ui.unit.TextUnit
2326import androidx.compose.ui.unit.dp
@@ -55,6 +58,7 @@ class ComposeMaskingOptionsTest {
5558 System .setProperty(" robolectric.areWindowsMarkedVisible" , " true" )
5659 System .setProperty(" robolectric.pixelCopyRenderMode" , " hardware" )
5760 ComposeMaskingOptionsActivity .textModifierApplier = null
61+ ComposeMaskingOptionsActivity .textFieldModifierApplier = null
5862 ComposeMaskingOptionsActivity .containerModifierApplier = null
5963 ComposeMaskingOptionsActivity .fontSizeApplier = null
6064 }
@@ -90,6 +94,23 @@ class ComposeMaskingOptionsTest {
9094 assertEquals(" Random repo" , (textNodes.first().layout as ? ComposeTextLayout )?.layout?.layoutInput?.text?.text)
9195 }
9296
97+ @Test
98+ fun `when text input field is readOnly still masks it` () {
99+ ComposeMaskingOptionsActivity .textFieldModifierApplier = {
100+ // newer versions of compose basically do this when a TextField is readOnly
101+ Modifier .clearAndSetSemantics { editableText = AnnotatedString (" Placeholder" ) }
102+ }
103+ val activity = buildActivity(ComposeMaskingOptionsActivity ::class .java).setup()
104+ shadowOf(Looper .getMainLooper()).idle()
105+
106+ val options = SentryOptions ().apply {
107+ sessionReplay.maskAllText = true
108+ }
109+
110+ val textNodes = activity.get().collectNodesOfType<TextViewHierarchyNode >(options)
111+ assertTrue(textNodes[1 ].shouldMask)
112+ }
113+
93114 @Test
94115 fun `when maskAllText is set to false all Text nodes are unmasked` () {
95116 val activity = buildActivity(ComposeMaskingOptionsActivity ::class .java).setup()
@@ -231,6 +252,7 @@ private class ComposeMaskingOptionsActivity : ComponentActivity() {
231252
232253 companion object {
233254 var textModifierApplier: (() -> Modifier )? = null
255+ var textFieldModifierApplier: (() -> Modifier )? = null
234256 var containerModifierApplier: (() -> Modifier )? = null
235257 var fontSizeApplier: (() -> TextUnit )? = null
236258 }
@@ -254,6 +276,7 @@ private class ComposeMaskingOptionsActivity : ComponentActivity() {
254276 )
255277 Text (" Random repo" , fontSize = fontSizeApplier?.invoke() ? : TextUnit .Unspecified )
256278 TextField (
279+ modifier = textFieldModifierApplier?.invoke() ? : Modifier ,
257280 value = TextFieldValue (" Placeholder" ),
258281 onValueChange = { _ -> }
259282 )
0 commit comments