diff --git a/Sources/SkipUI/Skip/Shadowed.kt b/Sources/SkipUI/Skip/Shadowed.kt index d52cbbd0..e57d4fa5 100644 --- a/Sources/SkipUI/Skip/Shadowed.kt +++ b/Sources/SkipUI/Skip/Shadowed.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.layout.Layout import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.semantics.clearAndSetSemantics import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Dp import kotlin.math.ceil @@ -28,7 +29,9 @@ import kotlin.math.ceil val blurRadiusPx = ceil(with(density) { blurRadius.toPx() }).toInt() val contentContext = context.content() + // The shadow is a second copy of the content: keep it out of the accessibility tree. val shadowContext = context.content(modifier = Modifier + .clearAndSetSemantics {} .drawWithContent { val matrix = shadowColorMatrix(color) val filter = ColorFilter.colorMatrix(matrix) diff --git a/Tests/SkipUITests/SkipUITests.swift b/Tests/SkipUITests/SkipUITests.swift index 60a5c6bc..991908b8 100644 --- a/Tests/SkipUITests/SkipUITests.swift +++ b/Tests/SkipUITests/SkipUITests.swift @@ -103,6 +103,7 @@ import androidx.compose.ui.test.junit4.ComposeContentTestRule import androidx.compose.ui.test.longClick import androidx.compose.ui.test.moveTo import androidx.compose.ui.test.onAllNodesWithTag +import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onFirst import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText @@ -519,6 +520,30 @@ final class SkipUITests: SkipUITestCase { } } + func testShadowCopyIsHiddenFromAccessibility() throws { + #if !SKIP + throw XCTSkip("Compose semantics") + #else + try testUI(view: { + Text("Shadowed").shadow(radius: 4) + }, eval: { rule in + rule.onAllNodesWithText("Shadowed").assertCountEquals(1) + }) + #endif + } + + func testShadowCopyOfButtonIsHiddenFromAccessibility() throws { + #if !SKIP + throw XCTSkip("Compose semantics") + #else + try testUI(view: { + Button("Tap") { }.shadow(radius: 4, y: 8) + }, eval: { rule in + rule.onAllNodes(hasClickAction()).assertCountEquals(1) + }) + #endif + } + func testMenuAccessibilityIdentifier() throws { try testUI(view: { MenuTestView().accessibilityIdentifier("test-view")