1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.compose.ui.test
18
19 import androidx.compose.ui.semantics.SemanticsNode
20
21 internal val SemanticsNode.siblings: List<SemanticsNode>
22 get() {
23 val node = this
<lambda>null24 return parent?.run { this.children.filter { it.id != node.id } } ?: emptyList()
25 }
26
27 /**
28 * Returns a parent of this node.
29 *
30 * Any subsequent operation on its result will expect exactly one element found (unless
31 * [SemanticsNodeInteraction.assertDoesNotExist] is used) and will throw [AssertionError] if none or
32 * more than one element is found.
33 */
SemanticsNodeInteractionnull34 fun SemanticsNodeInteraction.onParent(): SemanticsNodeInteraction {
35 return SemanticsNodeInteraction(
36 testContext,
37 useUnmergedTree,
38 selector.addSelectionFromSingleNode("parent") { listOfNotNull(it.parent) }
39 )
40 }
41
42 /** Returns children of this node. */
SemanticsNodeInteractionnull43 fun SemanticsNodeInteraction.onChildren(): SemanticsNodeInteractionCollection {
44 return SemanticsNodeInteractionCollection(
45 testContext,
46 useUnmergedTree,
47 selector.addSelectionFromSingleNode("children") { it.children }
48 )
49 }
50
51 /**
52 * Returns exactly one child of this node.
53 *
54 * Use this only if this node has exactly one child.
55 *
56 * Any subsequent operation on its result will expect exactly one element found (unless
57 * [SemanticsNodeInteraction.assertDoesNotExist] is used) and will throw [AssertionError] if none or
58 * more than one element is found.
59 */
SemanticsNodeInteractionnull60 fun SemanticsNodeInteraction.onChild(): SemanticsNodeInteraction {
61 return SemanticsNodeInteraction(
62 testContext,
63 useUnmergedTree,
64 selector.addSelectionFromSingleNode("child") { it.children }
65 )
66 }
67
68 /**
69 * Returns child of this node at the given index.
70 *
71 * This is just a shortcut for "children[index]".
72 */
onChildAtnull73 fun SemanticsNodeInteraction.onChildAt(index: Int): SemanticsNodeInteraction = onChildren()[index]
74
75 /**
76 * Returns all siblings of this node.
77 *
78 * Example: For the following tree
79 *
80 * ```
81 * |-A
82 * |-B1
83 * |-B2 <- this node
84 * |-B3
85 * Returns B1, B3
86 * ```
87 */
88 fun SemanticsNodeInteraction.onSiblings(): SemanticsNodeInteractionCollection {
89 return SemanticsNodeInteractionCollection(
90 testContext,
91 useUnmergedTree,
92 selector.addSelectionFromSingleNode("siblings") { it.siblings }
93 )
94 }
95
96 /**
97 * Returns exactly one sibling of this node.
98 *
99 * Use this only if this node has exactly one sibling.
100 *
101 * Any subsequent operation on its result will expect exactly one element found (unless
102 * [SemanticsNodeInteraction.assertDoesNotExist] is used) and will throw [AssertionError] if none or
103 * more than one element is found.
104 */
SemanticsNodeInteractionnull105 fun SemanticsNodeInteraction.onSibling(): SemanticsNodeInteraction {
106 return SemanticsNodeInteraction(
107 testContext,
108 useUnmergedTree,
109 selector.addSelectionFromSingleNode("sibling") { it.siblings }
110 )
111 }
112
113 /**
114 * Returns all the ancestors of this node.
115 *
116 * Example: For the following tree
117 *
118 * ```
119 * |-A
120 * |-B
121 * |-C <- this node
122 * Returns B, A
123 * ```
124 */
SemanticsNodeInteractionnull125 fun SemanticsNodeInteraction.onAncestors(): SemanticsNodeInteractionCollection {
126 return SemanticsNodeInteractionCollection(
127 testContext,
128 useUnmergedTree,
129 selector.addSelectionFromSingleNode("ancestors") { it.ancestors.toList() }
130 )
131 }
132
133 /**
134 * Returns the first node in this collection.
135 *
136 * Any subsequent operation on its result will expect exactly one element found (unless
137 * [SemanticsNodeInteraction.assertDoesNotExist] is used) and will throw [AssertionError] if no
138 * element is found.
139 */
onFirstnull140 fun SemanticsNodeInteractionCollection.onFirst(): SemanticsNodeInteraction {
141 return get(0)
142 }
143
144 /**
145 * Returns the last node in this collection.
146 *
147 * Any subsequent operation on its result will expect exactly one element found (unless
148 * [SemanticsNodeInteraction.assertDoesNotExist] is used) and will throw [AssertionError] if no
149 * element is found.
150 */
SemanticsNodeInteractionCollectionnull151 fun SemanticsNodeInteractionCollection.onLast(): SemanticsNodeInteraction {
152 return SemanticsNodeInteraction(testContext, useUnmergedTree, selector.addLastNodeSelector())
153 }
154
155 /**
156 * Returns all the nodes matching the given [matcher].
157 *
158 * @param matcher Matcher to use for the filtering.
159 */
filternull160 fun SemanticsNodeInteractionCollection.filter(
161 matcher: SemanticsMatcher
162 ): SemanticsNodeInteractionCollection {
163 return SemanticsNodeInteractionCollection(
164 testContext,
165 useUnmergedTree,
166 selector.addSelectorViaMatcher("filter", matcher)
167 )
168 }
169
170 /**
171 * Expects to return exactly one node matching the given [matcher].
172 *
173 * Any subsequent operation on its result will expect exactly one element found (unless
174 * [SemanticsNodeInteraction.assertDoesNotExist] is used) and will throw [AssertionError] if no
175 * element is found.
176 *
177 * @param matcher Matcher to use for the filtering.
178 */
filterToOnenull179 fun SemanticsNodeInteractionCollection.filterToOne(
180 matcher: SemanticsMatcher
181 ): SemanticsNodeInteraction {
182 return SemanticsNodeInteraction(
183 testContext,
184 useUnmergedTree,
185 selector.addSelectorViaMatcher("filterToOne", matcher)
186 )
187 }
188