REGRESSION(r184899): Crash when focusing an input element styled with a web font
[WebKit-https.git] / LayoutTests / platform / mac / accessibility / search-predicate.html
1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2 <html>
3 <head>
4 <script src="../../../resources/js-test-pre.js"></script>
5 </head>
6 <body id="body">
7
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>
12 <form>
13 <input type="text" /><br />
14 <input type="checkbox" value="Checkbox" /> checkbox<br />
15 <input type="submit" value="Submit" />
16 </form>
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>
30 <table>
31 <thead><tr><td>first table heading level 1</td></tr></thead>
32 <tbody><tr><td>first table body level 1</td></tr></tbody>
33 </table>
34 <table>
35 <thead><tr><td>second table heading level 1</td></tr></thead>
36 <tbody><tr><td>second table body level 1</td></tr></tbody>
37 </table>
38 <ul role="tree"><li role="treeitem">tree item</li></ul>
39
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>
53 </div>
54 <button id="button">test button 3</button>
55
56     
57 <p id="description"></p>
58 <div id="console"></div>
59
60 <script>
61     description("This tests the ability to search for accessible elements by key or text.");
62     
63     if (window.accessibilityController) {
64         window.testRunner.keepWebHistory();
65         
66         document.getElementById("body").focus();
67         var containerElement = accessibilityController.focusedElement;
68         var startElement;
69         var resultElement;
70         var testButton2;
71
72         // Any element.
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'");
77         
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'");
83         
84         // Blockquote.
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'");
89         
90         // Bold font.
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'");
95         
96         // Button.
97         startElement = accessibilityController.focusedElement.childAtIndex(0);
98         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
99         shouldBe("resultElement.role", "'AXRole: AXButton'");
100         
101         // Check box.
102         startElement = accessibilityController.focusedElement.childAtIndex(0);
103         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
104         shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
105         
106         // Control.
107         startElement = accessibilityController.focusedElement.childAtIndex(0);
108         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
109         shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
110         
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'");
116         
117         // Font change.
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'");
122         
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'");
128         
129         // Graphic.
130         startElement = accessibilityController.focusedElement.childAtIndex(0);
131         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXGraphicSearchKey", "", false);
132         shouldBe("resultElement.role", "'AXRole: AXImage'");
133         
134         // Heading level 1.
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'");
139         
140         // Heading level 2.
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'");
145         
146         // Heading level 3.
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'");
151         
152         // Heading level 4.
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'");
157         
158         // Heading level 5.
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'");
163         
164         // Heading level 6.
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'");
169         
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'");
175         
176         // Heading.
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'");
181         
182         // Italic font.
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'");
187         
188         // Landmark.
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'");
193         
194         // Link.
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'");
199         
200         // List.
201         startElement = accessibilityController.focusedElement.childAtIndex(0);
202         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXListSearchKey", "", false);
203         shouldBe("resultElement.role", "'AXRole: AXList'");
204         
205         // Live Region.
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'");
210         
211         // Misspelled word.
212         // FIXME: Handle this search key.
213         
214         // Outline.
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'");
219         
220         // Plain text.
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'");
225         
226         // Radio group.
227         startElement = accessibilityController.focusedElement.childAtIndex(0);
228         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXRadioGroupSearchKey", "", false);
229         shouldBe("resultElement.role", "'AXRole: AXRadioGroup'");
230         
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'");
236         
237         // Static text.
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'");
242         
243         // Style change.
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'");
248         
249         // Same level table.
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'");
254         
255         // Table.
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'");
260         
261         // Text field.
262         startElement = accessibilityController.focusedElement.childAtIndex(0);
263         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTextFieldSearchKey", "", false);
264         shouldBe("resultElement.role", "'AXRole: AXTextField'");
265         
266         // Underline.
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'");
271         
272         // Unvisited link.
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'");
277         
278         // Visited 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'");
284         
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'");
290         
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'");
296         
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'");
301
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'");
306                
307         // Now, we need to test isVisible. Save off the first object
308         startElement = accessibilityController.focusedElement.childAtIndex(0);
309         
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();
315         
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'");       
320         
321         // save away the "isVisible test start" heading as the start element
322         startElement = resultElement;
323         
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'");
328         
329         resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
330         shouldBe("resultElement.role", "'AXRole: AXButton'");
331         shouldBe("resultElement.title", "'AXTitle: test button 2'");
332         
333         // save away testButton2 so we can make it visible later
334         testButton2 = resultElement;
335
336         resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
337         shouldBe("resultElement.role", "'AXRole: AXButton'");
338         shouldBe("resultElement.title", "'AXTitle: test button 3'");
339
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'");
344         
345         resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
346         shouldBe("resultElement.role", "'AXRole: AXButton'");
347         shouldBe("resultElement.title", "'AXTitle: test button 3'");
348         
349         // now, scroll to the second button, and confirm that we don't see the first button
350         testButton2.scrollToMakeVisible();
351
352         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
353         shouldBe("resultElement.role", "'AXRole: AXButton'");
354         shouldBe("resultElement.title", "'AXTitle: test button 2'");
355         
356         resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
357         shouldBe("resultElement.role", "'AXRole: AXButton'");
358         shouldBe("resultElement.title", "'AXTitle: test button 3'");
359         
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'");
365         
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'");
371         
372         // there should be no more visible buttons
373         resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
374         shouldBeUndefined("resultElement");
375         
376     }
377     
378 </script>
379
380 <script src="../../../resources/js-test-post.js"></script>
381 </body>
382 </html>