Skip to content

Commit f5c5ecb

Browse files
romtsnclaude
andcommitted
fix(replay): Fix flaky ComposeMaskingOptionsTest (getsentry#5613)
The `when sentry-unmask modifier is set unmasks the node` test intermittently failed because Robolectric can report zero bounds for some nodes when running the full test class, making them invisible (shouldMask = isVisible && ...). Restructure the test to: - Explicitly find the "Make Request" node and assert it IS visible and unmasked - Assert other visible nodes remain masked, with a guard against empty iteration - Tolerate intermittent zero-bounds on non-identifiable nodes (Robolectric artifact) Validated with the repro from getsentry/repro#51: 20/20 passes (vs ~10% flake rate before the fix). Fixes getsentry#5585 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9f75779 commit f5c5ecb

1 file changed

Lines changed: 17 additions & 11 deletions

File tree

sentry-android-replay/src/test/java/io/sentry/android/replay/viewhierarchy/ComposeMaskingOptionsTest.kt

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -228,18 +228,24 @@ class ComposeMaskingOptionsTest {
228228

229229
val textNodes = activity.get().collectNodesOfType<TextViewHierarchyNode>(options)
230230
assertEquals(4, textNodes.size) // [TextField, Text, Button, Activity Title]
231-
textNodes.forEach {
232-
if ((it.layout as? ComposeTextLayout)?.layout?.layoutInput?.text?.text == "Make Request") {
233-
assertFalse(
234-
it.shouldMask,
235-
"Node with text ${(it.layout as? ComposeTextLayout)?.layout?.layoutInput?.text?.text} should not be masked",
236-
)
237-
} else {
238-
assertTrue(
239-
it.shouldMask,
240-
"Node with text ${(it.layout as? ComposeTextLayout)?.layout?.layoutInput?.text?.text} should be masked",
241-
)
231+
232+
val unmaskNode =
233+
textNodes.first {
234+
(it.layout as? ComposeTextLayout)?.layout?.layoutInput?.text?.text == "Make Request"
242235
}
236+
assertTrue(unmaskNode.isVisible, "The unmasked node must be visible for the test to be valid")
237+
assertFalse(unmaskNode.shouldMask, "Node with sentryReplayUnmask() should not be masked")
238+
239+
// Robolectric may intermittently report zero bounds for some nodes when running
240+
// the full test class, making them invisible (shouldMask = isVisible && ...).
241+
// Assert that all other visible nodes remain masked.
242+
val otherVisibleNodes = textNodes.filter { it !== unmaskNode && it.isVisible }
243+
assertTrue(otherVisibleNodes.isNotEmpty(), "Expected at least one other visible text node")
244+
otherVisibleNodes.forEach {
245+
assertTrue(
246+
it.shouldMask,
247+
"Node with text ${(it.layout as? ComposeTextLayout)?.layout?.layoutInput?.text?.text} should be masked",
248+
)
243249
}
244250
}
245251

0 commit comments

Comments
 (0)