@@ -18,6 +18,7 @@ package androidx.compose.ui.accessibility
1818
1919import androidx.compose.foundation.Image
2020import androidx.compose.foundation.clickable
21+ import androidx.compose.foundation.layout.Box
2122import androidx.compose.foundation.layout.Column
2223import androidx.compose.foundation.layout.Row
2324import androidx.compose.foundation.layout.size
@@ -46,15 +47,18 @@ import androidx.compose.ui.interop.runUIKitInstrumentedTestWithInterop
4647import androidx.compose.ui.platform.accessibility.CMPAccessibilityTraitTextView
4748import androidx.compose.ui.platform.testTag
4849import androidx.compose.ui.semantics.Role
50+ import androidx.compose.ui.semantics.contentDescription
4951import androidx.compose.ui.semantics.heading
5052import androidx.compose.ui.semantics.isTraversalGroup
5153import androidx.compose.ui.semantics.role
5254import androidx.compose.ui.semantics.semantics
5355import androidx.compose.ui.semantics.testTag
56+ import androidx.compose.ui.semantics.text
5457import androidx.compose.ui.state.ToggleableState
5558import androidx.compose.ui.test.assertAccessibilityTree
5659import androidx.compose.ui.test.findNodeWithTag
5760import androidx.compose.ui.test.runUIKitInstrumentedTest
61+ import androidx.compose.ui.text.AnnotatedString
5862import androidx.compose.ui.text.buildAnnotatedString
5963import androidx.compose.ui.unit.dp
6064import androidx.compose.ui.viewinterop.UIKitInteropProperties
@@ -718,7 +722,7 @@ class ComponentsAccessibilitySemanticTest {
718722 }
719723
720724 assertAccessibilityTree {
721- label = " Foo\n Bar "
725+ label = " Foo, Bar "
722726 identifier = " row"
723727 isAccessibilityElement = true
724728 traits(UIAccessibilityTraitButton )
@@ -749,7 +753,7 @@ class ComponentsAccessibilitySemanticTest {
749753 }
750754
751755 assertAccessibilityTree {
752- value = " Label"
756+ label = " Label"
753757 isAccessibilityElement = true
754758 traits(CMPAccessibilityTraitTextView )
755759 }
@@ -766,7 +770,7 @@ class ComponentsAccessibilitySemanticTest {
766770 }
767771
768772 assertAccessibilityTree {
769- value = " Placeholder"
773+ label = " Placeholder"
770774 isAccessibilityElement = true
771775 traits(CMPAccessibilityTraitTextView )
772776 }
@@ -789,4 +793,218 @@ class ComponentsAccessibilitySemanticTest {
789793 traits(CMPAccessibilityTraitTextView )
790794 }
791795 }
796+
797+ @Test
798+ fun testNodeHierarchyInsideAccessibilityElementShouldNotFlatten () = runUIKitInstrumentedTest {
799+ setContent {
800+ Column (modifier = Modifier .clickable {}) {
801+ Text (" Title 1" )
802+ Row (modifier = Modifier .testTag(" Tag 1" )) {
803+ Text (" Description 1" )
804+ Text (" Details 1" )
805+ }
806+ }
807+ }
808+
809+ assertAccessibilityTree {
810+ isAccessibilityElement = true
811+ label = " Title 1, Description 1, Details 1"
812+ node {
813+ label = " Title 1"
814+ isAccessibilityElement = false
815+ }
816+ node {
817+ identifier = " Tag 1"
818+ isAccessibilityElement = false
819+ node {
820+ label = " Description 1"
821+ isAccessibilityElement = false
822+ }
823+ node {
824+ label = " Details 1"
825+ isAccessibilityElement = false
826+ }
827+ }
828+ }
829+ }
830+
831+ @Test
832+ fun testNodeHierarchyInsideTraversalGroupShouldFlatten () = runUIKitInstrumentedTest {
833+ setContent {
834+ Column {
835+ Column (modifier = Modifier .semantics { isTraversalGroup = true }) {
836+ Text (" Title 1" )
837+ Row (modifier = Modifier .testTag(" Tag 1" )) {
838+ Text (" Description 1" )
839+ Text (" Details 1" )
840+ }
841+ }
842+ Column (modifier = Modifier .semantics { isTraversalGroup = true }) {
843+ Text (" Title 2" )
844+ }
845+ }
846+ }
847+
848+ assertAccessibilityTree {
849+ node {
850+ node {
851+ label = " Title 1"
852+ isAccessibilityElement = true
853+ }
854+ node {
855+ label = " Description 1"
856+ isAccessibilityElement = true
857+ }
858+ node {
859+ identifier = " Tag 1"
860+ isAccessibilityElement = false
861+ }
862+ node {
863+ label = " Details 1"
864+ isAccessibilityElement = true
865+ }
866+ }
867+ node {
868+ label = " Title 2"
869+ isAccessibilityElement = true
870+ }
871+ }
872+ }
873+
874+ @Test
875+ fun testReplacedTextContent () = runUIKitInstrumentedTest {
876+ setContent {
877+ Text (" Text" , modifier = Modifier .semantics {
878+ text = AnnotatedString (" Replaced" )
879+ })
880+ }
881+
882+ assertAccessibilityTree {
883+ label = " Replaced"
884+ }
885+ }
886+
887+ @Test
888+ fun testReplacedContentWithMergedSemantics () = runUIKitInstrumentedTest {
889+ setContent {
890+ Box (modifier = Modifier .size(50 .dp).semantics(mergeDescendants = true ) {
891+ text = AnnotatedString (" Text" )
892+ contentDescription = " Description"
893+ }) {
894+ Text (" Text" )
895+ }
896+ }
897+
898+ assertAccessibilityTree {
899+ label = " Description, Text"
900+ isAccessibilityElement = true
901+ node {
902+ label = " Text"
903+ isAccessibilityElement = false
904+ }
905+ }
906+ }
907+
908+ @Test
909+ fun testReplacedContentWithoutMergedSemantics () = runUIKitInstrumentedTest {
910+ setContent {
911+ Box (modifier = Modifier .size(50 .dp).semantics {
912+ contentDescription = " Description"
913+ }) {
914+ Text (" Text" )
915+ }
916+ }
917+
918+ assertAccessibilityTree {
919+ node {
920+ label = " Text"
921+ isAccessibilityElement = true
922+ }
923+ node {
924+ label = " Description"
925+ isAccessibilityElement = true
926+ }
927+ }
928+ }
929+
930+ @Test
931+ fun testContentReplacedSemanticsWithChildElement () = runUIKitInstrumentedTest {
932+ setContent {
933+ Box (modifier = Modifier .semantics(mergeDescendants = true ) {
934+ text = AnnotatedString (" Text" )
935+ contentDescription = " Description"
936+ }) {
937+ Box (modifier = Modifier .size(50 .dp).testTag(" Child" ))
938+ }
939+ }
940+
941+ assertAccessibilityTree {
942+ label = " Description"
943+ isAccessibilityElement = true
944+ node {
945+ identifier = " Child"
946+ }
947+ }
948+ }
949+
950+ @Test
951+ fun testEnclosedComplexContentWithMergedSemantics () = runUIKitInstrumentedTest {
952+ setContent {
953+ Column (modifier = Modifier .semantics(mergeDescendants = true ) {
954+ text = AnnotatedString (" Text" )
955+ contentDescription = " Description"
956+ }) {
957+ Box (modifier = Modifier .size(50 .dp).semantics {
958+ contentDescription = " Inner"
959+ }) {
960+ TextField (
961+ value = " " ,
962+ onValueChange = {},
963+ label = { Text (" Label" ) },
964+ placeholder = { Text (" Placeholder" ) }
965+ )
966+ }
967+ Column (modifier = Modifier .semantics(mergeDescendants = true ) {}) {
968+ Text (text = " First Text" )
969+ Text (text = " Second Text" )
970+ }
971+ Text (text = " Text" )
972+ }
973+ }
974+
975+ assertAccessibilityTree {
976+ node {
977+ isAccessibilityElement = true
978+ label = " Label"
979+ node {
980+ label = " Label"
981+ isAccessibilityElement = false
982+ }
983+ }
984+ node {
985+ label = " Description, Inner, Text"
986+ isAccessibilityElement = true
987+ node {
988+ label = " Inner"
989+ isAccessibilityElement = false
990+ }
991+ node {
992+ label = " Text"
993+ isAccessibilityElement = false
994+ }
995+ }
996+ node {
997+ label = " First Text, Second Text"
998+ isAccessibilityElement = true
999+ node {
1000+ label = " First Text"
1001+ isAccessibilityElement = false
1002+ }
1003+ node {
1004+ label = " Second Text"
1005+ isAccessibilityElement = false
1006+ }
1007+ }
1008+ }
1009+ }
7921010}
0 commit comments