1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
4 <script src="../../resources/js-test-pre.js"></script>
8 <blockquote>first blockquote level 1</blockquote>
9 <blockquote>second blockquote level 1</blockquote>
10 <p style="color:black; font-family:sans-serif; font-weight:bold; text-decoration:underline;">sans-serif black bold text with underline</p>
11 <p style="color:blue; font-family:serif; font-style:italic;">serif blue italic text</p>
13 <input type="text" /><br />
14 <input type="checkbox" value="Checkbox" /> checkbox<br />
15 <input type="submit" value="Submit" />
17 <img id="image" src="resources/cake.png" alt="Test">
18 <h1>first heading level 1</h1>
19 <h1>second heading level 1</h1>
20 <h2>heading level 2</h2>
21 <h3>heading level 3</h3>
22 <h4>heading level 4</h4>
23 <h5>heading level 5</h5>
24 <h6>heading level 6</h6>
25 <p id="banner" role="banner">landmark</p>
26 <a href="#image">link</a>
27 <ol><li>list item</li></ol>
28 <p aria-live="polite">live region</p>
29 <ul role="radiogroup"><li role="radio">radio button</li></ul>
31 <thead><tr><td>first table heading level 1</td></tr></thead>
32 <tbody><tr><td>first table body level 1</td></tr></tbody>
35 <thead><tr><td>second table heading level 1</td></tr></thead>
36 <tbody><tr><td>second table body level 1</td></tr></tbody>
38 <ul role="tree"><li role="treeitem">tree item</li></ul>
40 <h1>isVisible test start</h1>
41 <div id="group" style="overflow: scroll; width:100px; height:100px;">
42 <button id="button">test button 1</button><BR>
43 test test test test <br>
44 test test test test <br>
45 test test test test <br>
46 test test test test <br>
47 test test test test <br>
48 test test test test <br>
49 test test test test <br>
50 test test test test <br>
51 test test test test <br>
52 <button id="button">test button 2</button>
54 <button id="button">test button 3</button>
57 <p id="description"></p>
58 <div id="console"></div>
61 description("This tests the ability to search for accessible elements by key or text.");
63 if (window.accessibilityController) {
64 window.testRunner.keepWebHistory();
66 document.getElementById("body").focus();
67 var containerElement = accessibilityController.focusedElement;
73 startElement = accessibilityController.focusedElement.childAtIndex(0);
74 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXAnyTypeSearchKey", "", false);
75 shouldBe("resultElement.role", "'AXRole: AXStaticText'");
76 shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
78 // Same level blockquote.
79 startElement = accessibilityController.focusedElement.childAtIndex(0);
80 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSameLevelSearchKey", "", false);
81 shouldBe("resultElement.role", "'AXRole: AXGroup'");
82 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
85 startElement = accessibilityController.focusedElement.childAtIndex(0);
86 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSearchKey", "", false);
87 shouldBe("resultElement.role", "'AXRole: AXGroup'");
88 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
91 startElement = accessibilityController.focusedElement.childAtIndex(0);
92 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBoldFontSearchKey", "", false);
93 shouldBe("resultElement.role", "'AXRole: AXGroup'");
94 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: sans-serif black bold text with underline'");
97 startElement = accessibilityController.focusedElement.childAtIndex(0);
98 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
99 shouldBe("resultElement.role", "'AXRole: AXButton'");
102 startElement = accessibilityController.focusedElement.childAtIndex(0);
103 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
104 shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
107 startElement = accessibilityController.focusedElement.childAtIndex(0);
108 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
109 shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
111 // Different type element.
112 startElement = accessibilityController.focusedElement.childAtIndex(0);
113 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXDifferentTypeSearchKey", "", false);
114 shouldBe("resultElement.role", "'AXRole: AXStaticText'");
115 shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
118 startElement = accessibilityController.focusedElement.childAtIndex(2);
119 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontChangeSearchKey", "", false);
120 shouldBe("resultElement.role", "'AXRole: AXGroup'");
121 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
123 // Font color change.
124 startElement = accessibilityController.focusedElement.childAtIndex(2);
125 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontColorChangeSearchKey", "", false);
126 shouldBe("resultElement.role", "'AXRole: AXGroup'");
127 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
130 startElement = accessibilityController.focusedElement.childAtIndex(0);
131 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXGraphicSearchKey", "", false);
132 shouldBe("resultElement.role", "'AXRole: AXImage'");
135 startElement = accessibilityController.focusedElement.childAtIndex(0);
136 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel1SearchKey", "", false);
137 shouldBe("resultElement.role", "'AXRole: AXHeading'");
138 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: first heading level 1'");
141 startElement = accessibilityController.focusedElement.childAtIndex(0);
142 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel2SearchKey", "", false);
143 shouldBe("resultElement.role", "'AXRole: AXHeading'");
144 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
147 startElement = accessibilityController.focusedElement.childAtIndex(0);
148 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel3SearchKey", "", false);
149 shouldBe("resultElement.role", "'AXRole: AXHeading'");
150 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 3'");
153 startElement = accessibilityController.focusedElement.childAtIndex(0);
154 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel4SearchKey", "", false);
155 shouldBe("resultElement.role", "'AXRole: AXHeading'");
156 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 4'");
159 startElement = accessibilityController.focusedElement.childAtIndex(0);
160 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel5SearchKey", "", false);
161 shouldBe("resultElement.role", "'AXRole: AXHeading'");
162 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 5'");
165 startElement = accessibilityController.focusedElement.childAtIndex(0);
166 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel6SearchKey", "", false);
167 shouldBe("resultElement.role", "'AXRole: AXHeading'");
168 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 6'");
170 // Same level heading.
171 startElement = accessibilityController.focusedElement.childAtIndex(6);
172 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSameLevelSearchKey", "", false);
173 shouldBe("resultElement.role", "'AXRole: AXHeading'");
174 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second heading level 1'");
177 startElement = accessibilityController.focusedElement.childAtIndex(0);
178 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSearchKey", "", false);
179 shouldBe("resultElement.role", "'AXRole: AXHeading'");
180 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: first heading level 1'");
183 startElement = accessibilityController.focusedElement.childAtIndex(0);
184 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXItalicFontSearchKey", "", false);
185 shouldBe("resultElement.role", "'AXRole: AXGroup'");
186 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
189 startElement = accessibilityController.focusedElement.childAtIndex(0);
190 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLandmarkSearchKey", "", false);
191 shouldBe("resultElement.role", "'AXRole: AXGroup'");
192 shouldBe("resultElement.subrole", "'AXSubrole: AXLandmarkBanner'");
195 startElement = accessibilityController.focusedElement.childAtIndex(0);
196 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLinkSearchKey", "", false);
197 shouldBe("resultElement.role", "'AXRole: AXLink'");
198 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
201 startElement = accessibilityController.focusedElement.childAtIndex(0);
202 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXListSearchKey", "", false);
203 shouldBe("resultElement.role", "'AXRole: AXList'");
206 startElement = accessibilityController.focusedElement.childAtIndex(0);
207 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLiveRegionSearchKey", "", false);
208 shouldBe("resultElement.role", "'AXRole: AXGroup'");
209 shouldBe("resultElement.stringAttributeValue('AXARIALive')", "'polite'");
212 // FIXME: Handle this search key.
215 startElement = accessibilityController.focusedElement.childAtIndex(0);
216 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXOutlineSearchKey", "", false);
217 shouldBe("resultElement.role", "'AXRole: AXOutline'");
218 shouldBe("resultElement.childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: tree item'");
221 startElement = accessibilityController.focusedElement.childAtIndex(0);
222 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXPlainTextSearchKey", "", false);
223 shouldBe("resultElement.role", "'AXRole: AXStaticText'");
224 shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
227 startElement = accessibilityController.focusedElement.childAtIndex(0);
228 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXRadioGroupSearchKey", "", false);
229 shouldBe("resultElement.role", "'AXRole: AXRadioGroup'");
231 // Same type element.
232 startElement = accessibilityController.focusedElement.childAtIndex(0);
233 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXSameTypeSearchKey", "", false);
234 shouldBe("resultElement.role", "'AXRole: AXGroup'");
235 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
238 startElement = accessibilityController.focusedElement.childAtIndex(0);
239 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStaticTextSearchKey", "", false);
240 shouldBe("resultElement.role", "'AXRole: AXStaticText'");
241 shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
244 startElement = accessibilityController.focusedElement.childAtIndex(2);
245 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStyleChangeSearchKey", "", false);
246 shouldBe("resultElement.role", "'AXRole: AXGroup'");
247 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
250 startElement = accessibilityController.focusedElement.childAtIndex(18);
251 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSameLevelSearchKey", "", false);
252 shouldBe("resultElement.role", "'AXRole: AXTable'");
253 shouldBe("resultElement.childAtIndex(0).childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: second table heading level 1'");
256 startElement = accessibilityController.focusedElement.childAtIndex(0);
257 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSearchKey", "", false);
258 shouldBe("resultElement.role", "'AXRole: AXTable'");
259 shouldBe("resultElement.childAtIndex(0).childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: first table heading level 1'");
262 startElement = accessibilityController.focusedElement.childAtIndex(0);
263 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTextFieldSearchKey", "", false);
264 shouldBe("resultElement.role", "'AXRole: AXTextField'");
267 startElement = accessibilityController.focusedElement.childAtIndex(0);
268 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnderlineSearchKey", "", false);
269 shouldBe("resultElement.role", "'AXRole: AXGroup'");
270 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: sans-serif black bold text with underline'");
273 startElement = accessibilityController.focusedElement.childAtIndex(0);
274 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnvisitedLinkSearchKey", "", false);
275 shouldBe("resultElement.boolAttributeValue('AXVisited')", "false");
276 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
279 accessibilityController.focusedElement.childAtIndex(14).childAtIndex(0).press();
280 startElement = accessibilityController.focusedElement.childAtIndex(0);
281 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXVisitedLinkSearchKey", "", false);
282 shouldBe("resultElement.boolAttributeValue('AXVisited')", "true");
283 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
285 // Previous text search.
286 startElement = accessibilityController.focusedElement.childAtIndex(10);
287 resultElement = containerElement.uiElementForSearchPredicate(startElement, false, "", "sans-serif black bold text with underline", false);
288 shouldBe("resultElement.role", "'AXRole: AXStaticText'");
289 shouldBe("resultElement.stringValue", "'AXValue: sans-serif black bold text with underline'");
291 // Execute a search for the next heading level 2 or the next link.
292 startElement = accessibilityController.focusedElement.childAtIndex(0);
293 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
294 shouldBe("resultElement.role", "'AXRole: AXHeading'");
295 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
297 // After finding the heading, execute the search again and we should find the link.
298 resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
299 shouldBe("resultElement.role", "'AXRole: AXLink'");
300 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
302 // From the link, execute the search in reverse and we should land back on the heading.
303 resultElement = containerElement.uiElementForSearchPredicate(resultElement, false, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
304 shouldBe("resultElement.role", "'AXRole: AXHeading'");
305 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
307 // Now, we need to test isVisible. Save off the first object
308 startElement = accessibilityController.focusedElement.childAtIndex(0);
310 // Scroll all the way to the bottom of the content
311 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "test button 3", false);
312 shouldBe("resultElement.role", "'AXRole: AXButton'");
313 shouldBe("resultElement.title", "'AXTitle: test button 3'");
314 resultElement.scrollToMakeVisible();
316 // find the start of the isVisible test section
317 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "isVisible test start", false);
318 shouldBe("resultElement.role", "'AXRole: AXHeading'");
319 shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: isVisible test start'");
321 // save away the "isVisible test start" heading as the start element
322 startElement = resultElement;
324 // If we don't care about visible only, then we should easily find 3 buttons
325 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
326 shouldBe("resultElement.role", "'AXRole: AXButton'");
327 shouldBe("resultElement.title", "'AXTitle: test button 1'");
329 resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
330 shouldBe("resultElement.role", "'AXRole: AXButton'");
331 shouldBe("resultElement.title", "'AXTitle: test button 2'");
333 // save away testButton2 so we can make it visible later
334 testButton2 = resultElement;
336 resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
337 shouldBe("resultElement.role", "'AXRole: AXButton'");
338 shouldBe("resultElement.title", "'AXTitle: test button 3'");
340 // if we care about visible only, then we should not find "test button 2"
341 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
342 shouldBe("resultElement.role", "'AXRole: AXButton'");
343 shouldBe("resultElement.title", "'AXTitle: test button 1'");
345 resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
346 shouldBe("resultElement.role", "'AXRole: AXButton'");
347 shouldBe("resultElement.title", "'AXTitle: test button 3'");
349 // now, scroll to the second button, and confirm that we don't see the first button
350 testButton2.scrollToMakeVisible();
352 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
353 shouldBe("resultElement.role", "'AXRole: AXButton'");
354 shouldBe("resultElement.title", "'AXTitle: test button 2'");
356 resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
357 shouldBe("resultElement.role", "'AXRole: AXButton'");
358 shouldBe("resultElement.title", "'AXTitle: test button 3'");
360 // Now since the page is scrolled to the bottom, the first visible button should be #2
361 startElement = accessibilityController.focusedElement.childAtIndex(0);
362 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
363 shouldBe("resultElement.role", "'AXRole: AXButton'");
364 shouldBe("resultElement.title", "'AXTitle: test button 2'");
366 // lets scroll to the top of the page and ensure that the submit button is visible
367 startElement.scrollToMakeVisible();
368 resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
369 shouldBe("resultElement.role", "'AXRole: AXButton'");
370 shouldBe("resultElement.title", "'AXTitle: Submit'");
372 // there should be no more visible buttons
373 resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
374 shouldBeUndefined("resultElement");
380 <script src="../../resources/js-test-post.js"></script>