1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 package ifc.accessibility;
24 
25 import com.sun.star.accessibility.AccessibleRole;
26 import com.sun.star.accessibility.XAccessible;
27 import com.sun.star.accessibility.XAccessibleContext;
28 import com.sun.star.accessibility.XAccessibleSelection;
29 import com.sun.star.uno.UnoRuntime;
30 
31 import lib.MultiMethodTest;
32 import lib.Status;
33 import lib.StatusException;
34 
35 
36 /**
37  * Testing <code>com.sun.star.accessibility.XAccessibleSelection</code>
38  * interface methods :
39  * <ul>
40  *  <li><code>selectAccessibleChild()</code></li>
41  *  <li><code>isAccessibleChildSelected()</code></li>
42  *  <li><code>clearAccessibleSelection()</code></li>
43  *  <li><code>selectAllAccessibleChildren()</code></li>
44  *  <li><code>getSelectedAccessibleChildCount()</code></li>
45  *  <li><code>getSelectedAccessibleChild()</code></li>
46  *  <li><code>deselectAccessibleChild()</code></li>
47  * </ul> <p>
48  *
49  * This test needs the following object relations :
50  * <ul>
51  *  <li> <code>'XAccessibleSelection.multiSelection'</code>
52  *  (of type <code>Boolean</code>) <b> optional </b>:
53  *   Indicates whether or not mutiply children could be selected.
54  *   If the relation is <code>false</code> then more than 1 child
55  *   couldn't be selected. </li>
56  * </ul> <p>
57  *
58  * @see com.sun.star.accessibility.XAccessibleSelection
59  */
60 public class _XAccessibleSelection extends MultiMethodTest {
61     private static final String className = "com.sun.star.accessibility.XAccessibleSelection";
62     public XAccessibleSelection oObj = null;
63     XAccessibleContext xAC = null;
64     int childCount;
65     protected boolean multiSelection = true;
66     protected boolean OneAlwaysSelected = false;
67 
68     // temporary while accessibility package is in com.sun.star
getTestedClassName()69     protected String getTestedClassName() {
70         return className;
71     }
72 
73     /**
74      * Retrieves the interface <code>XAccessibleContext</code>
75      * and object relation.
76      * @see com.sun.star.accessibility.XAccessibleContext
77      * @see ifc.accessibility._XAccessibleContext
78      */
before()79     protected void before() {
80         xAC = (XAccessibleContext) UnoRuntime.queryInterface(
81                       XAccessibleContext.class, oObj);
82 
83         if (xAC == null) {
84             throw new StatusException(Status.failed(
85                                               "Couldn't query XAccessibleContext. Test must be modified"));
86         }
87 
88         Boolean b = (Boolean) tEnv.getObjRelation(
89                             "XAccessibleSelection.multiSelection");
90 
91         if (b != null) {
92             multiSelection = b.booleanValue();
93         }
94 
95         Boolean b2 = (Boolean) tEnv.getObjRelation(
96                              "XAccessibleSelection.OneAlwaysSelected");
97 
98         if (b2 != null) {
99             OneAlwaysSelected = b2.booleanValue();
100         }
101 
102         childCount = xAC.getAccessibleChildCount();
103         log.println("Child count: " + childCount);
104     }
105 
106     /**
107      * Selects accessible child with index some wrong indexes
108      * and with legal index.
109      * Has OK status if exception was thrown for wrong indexes
110      * and if exception wasn't thrown for correct index.
111      */
_selectAccessibleChild()112     public void _selectAccessibleChild() {
113         boolean res = true;
114 
115         try {
116             log.println("Try to select child with index " + childCount);
117             oObj.selectAccessibleChild(childCount);
118             log.println("Exception was expected");
119             res = false;
120         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
121             log.println("Expected exception");
122             res = true;
123         }
124 
125         try {
126             log.println("Try to select child with index -1");
127             oObj.selectAccessibleChild(-1);
128             log.println("Exception was expected");
129             res = false;
130         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
131             log.println("Expected exception");
132             res &= true;
133         }
134 
135         log.println("ChildCount: " + childCount);
136 
137         int usedChilds = childCount;
138 
139         if (childCount > 500) {
140             log.println("Restricting to 500");
141             usedChilds = 500;
142         }
143 
144         if (usedChilds > 0) {
145             try {
146                 for (int i = 0; i < usedChilds; i++) {
147                     log.print("Trying to select child with index " + i + ": ");
148 
149                     if (isSelectable(tEnv.getTestObject(), i)) {
150                         oObj.selectAccessibleChild(i);
151                         log.println("OK");
152                     } else {
153                         log.println("Child isn't selectable");
154                     }
155                 }
156 
157                 res &= true;
158             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
159                 log.println("Unexpected exception");
160                 e.printStackTrace(log);
161                 res = false;
162             }
163         }
164 
165         tRes.tested("selectAccessibleChild()", res);
166     }
167 
168     /**
169      * Calls the method with the wrong index and with the correct index.
170      * Has OK status if exception was thrown for wrong index and
171      * if exception wasn't thrown for the correct index.
172      */
_isAccessibleChildSelected()173     public void _isAccessibleChildSelected() {
174         executeMethod("selectAccessibleChild()");
175 
176         boolean res = true;
177         boolean isSelected = false;
178 
179         try {
180             log.print("isAccessibleChildSelected(-1)? ");
181             isSelected = oObj.isAccessibleChildSelected(-1);
182             log.println(res);
183             log.println("Exception was expected");
184             res = false;
185         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
186             log.println("Expected exception");
187             res = true;
188         }
189 
190         try {
191             log.print("isAccessibleChildSelected(" + childCount + ")? ");
192             isSelected = oObj.isAccessibleChildSelected(childCount);
193             log.println(isSelected);
194             log.println("Exception was expected");
195             res = false;
196         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
197             log.println("Expected exception");
198             res &= true;
199         }
200 
201         int SelectableChildCount = chkSelectable(tEnv.getTestObject());
202 
203         if (SelectableChildCount > 500) {
204             SelectableChildCount = 500;
205         }
206 
207         log.println("SelectableChildCount: " + SelectableChildCount);
208 
209         if (SelectableChildCount > 0) {
210             try {
211                 oObj.selectAllAccessibleChildren();
212 
213                 for (int k = 0; k < SelectableChildCount; k++) {
214                     log.println("Trying to select child with index " + k);
215 
216                     if (isSelectable(tEnv.getTestObject(), k)) {
217                         oObj.selectAccessibleChild(k);
218                         shortWait();
219                         isSelected = oObj.isAccessibleChildSelected(k);
220                         log.println("isAccessibleChildSelected - " +
221                                     isSelected);
222                         res &= isSelected;
223                     } else {
224                         log.println("Child isn't selectable");
225                     }
226                 }
227             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
228                 log.println("Unexpected exception");
229                 e.printStackTrace(log);
230                 res = false;
231             }
232         }
233 
234         tRes.tested("isAccessibleChildSelected()", res);
235     }
236 
237     /**
238      * Calls the method.
239      * Has OK status if the method <code>isAccessibleChildSelected()</code>
240      * returned <code>false</code>.
241      */
_clearAccessibleSelection()242     public void _clearAccessibleSelection() {
243         executeMethod("isAccessibleChildSelected()");
244 
245         boolean res = true;
246 
247         log.println("clearAccessibleSelection");
248         oObj.clearAccessibleSelection();
249 
250 
251         // clearAccessibleSelection() call is oneway so we need
252         // some waiting
253         shortWait();
254 
255         if ((childCount > 0) && !OneAlwaysSelected) {
256             try {
257                 log.print("isAccessibleChildSelected(" + (childCount - 1) +
258                           ")? ");
259 
260                 boolean isSel = oObj.isAccessibleChildSelected(childCount - 1);
261                 log.println(isSel);
262                 res = !isSel;
263             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
264                 log.println("Unexpected exception");
265                 e.printStackTrace(log);
266                 res = false;
267             }
268         } else if (OneAlwaysSelected) {
269             log.println("Can't clear selection, one child is always selected");
270         }
271 
272         tRes.tested("clearAccessibleSelection()", res);
273     }
274 
275     /**
276      * Calls the method.
277      * Has OK status if the method <code>isAccessibleChildSelected()</code>
278      * returns <code>true</code> for first and for last accessible child
279      * or if multiselection is not allowed.
280      */
_selectAllAccessibleChildren()281     public void _selectAllAccessibleChildren() {
282         executeMethod("clearAccessibleSelection()");
283 
284         log.println("selectAllAccessibleChildren...");
285         oObj.selectAllAccessibleChildren();
286 
287 
288         // selectAllAccessibleChildren() call is oneway so we need
289         // some waiting
290         shortWait();
291 
292         boolean res = true;
293         boolean isSelected = true;
294 
295         int SelectableChildCount = chkSelectable(tEnv.getTestObject());
296 
297         if ((SelectableChildCount > 0) && multiSelection) {
298             try {
299                 log.print("isAccessibleChildSelected(1)? ");
300                 isSelected = oObj.isAccessibleChildSelected(1);
301                 log.println(isSelected);
302                 res = isSelected;
303 
304                 log.print("isAccessibleChildSelected(" + (childCount - 1) +
305                           ")? ");
306                 isSelected = oObj.isAccessibleChildSelected(childCount - 1);
307                 log.println(isSelected);
308                 res &= isSelected;
309             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
310                 log.println("Unexpected exception");
311                 e.printStackTrace(log);
312                 res = false;
313             }
314         }
315 
316         tRes.tested("selectAllAccessibleChildren()", res);
317     }
318 
319     /**
320      * Calls the method. Clears accessible selection and calls the method again.
321      * <p>
322      * Has OK status if the method returns number equal to number of accessible
323      * child count after first call if multiselection allowed, or
324      * 1 returned if multiselection not allowed.
325      * And if the method returns a zero after clearing selection.
326      */
_getSelectedAccessibleChildCount()327     public void _getSelectedAccessibleChildCount() {
328         log.println("getSelectedAccessibleChildCount():");
329 
330         if (multiSelection) {
331             oObj.selectAllAccessibleChildren();
332         } else {
333             int usedChilds = childCount;
334 
335             if (childCount > 500) {
336                 log.println("Restricting to 500");
337                 usedChilds = 500;
338             }
339 
340             if (usedChilds > 0) {
341                 try {
342                     for (int i = 0; i < usedChilds; i++) {
343 
344                         if (isSelectable(tEnv.getTestObject(), i)) {
345                             log.print("Trying to select child with index "+i+": ");
346                             oObj.selectAccessibleChild(i);
347                             long curtime = System.currentTimeMillis();
348                             long checktime = System.currentTimeMillis();
349 
350                             while (!oObj.isAccessibleChildSelected(i) && (checktime-curtime<5000)) {
351                                 checktime = System.currentTimeMillis();
352                             }
353 
354                             log.println("OK");
355                         }
356                     }
357                 } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
358                     log.println("Unexpected exception");
359                     e.printStackTrace(log);
360                 }
361             }
362         }
363 
364         int sCount = chkSelectable(tEnv.getTestObject());
365         log.println("Found " + sCount + " selectable Childs");
366 
367         int selectedCount = oObj.getSelectedAccessibleChildCount();
368         log.println("After selecting all accessible " + selectedCount +
369                     " are selected");
370 
371         boolean res = true;
372 
373         if (multiSelection) {
374             res &= (selectedCount == sCount);
375         } else {
376             res &= (selectedCount == 1);
377         }
378 
379         log.println("clearAccessibleSelection...");
380         oObj.clearAccessibleSelection();
381         log.print("getSelectedAccessibleChildCount: ");
382         selectedCount = oObj.getSelectedAccessibleChildCount();
383         log.println(selectedCount);
384 
385         if (OneAlwaysSelected) {
386             res &= (selectedCount == 1);
387         } else {
388             res &= (selectedCount == 0);
389         }
390 
391         tRes.tested("getSelectedAccessibleChildCount()", res);
392     }
393 
394     /**
395      * Calls the method with wrong and correct indexes.
396      * Has OK status if exception was thrown for the wrong indexes,
397      * if exception wasn't thrown for the correct index and
398      * if the method have returned a not null for the correct index.
399      */
_getSelectedAccessibleChild()400     public void _getSelectedAccessibleChild() {
401         executeMethod("getSelectedAccessibleChildCount()");
402 
403         boolean res = true;
404         int selectedCount = oObj.getSelectedAccessibleChildCount();
405         log.println("getSelectedAccessibleChildCount: " + selectedCount);
406 
407         try {
408             log.println("getSelectedAccessibleChild(-1)");
409             oObj.getSelectedAccessibleChild(-1);
410             log.println("Exception was expected");
411             res = false;
412         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
413             log.println("Expected exception");
414             res = true;
415         }
416 
417         try {
418             log.println("getSelectedAccessibleChild(" + selectedCount + ")");
419             oObj.getSelectedAccessibleChild(selectedCount);
420             log.println("Exception was expected");
421             res &= false;
422         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
423             log.println("Expected exception");
424             res &= true;
425         }
426 
427         int SelectableChildCount = chkSelectable(tEnv.getTestObject());
428 
429         if (SelectableChildCount > 500) {
430             SelectableChildCount = 500;
431         }
432 
433         if (SelectableChildCount > 0) {
434             int k = 0;
435             try {
436                 for (k = 0; k < SelectableChildCount; k++) {
437                     log.println("Trying to select child with index " + k);
438 
439                     if (isSelectable(tEnv.getTestObject(), k)) {
440                         oObj.selectAccessibleChild(k);
441                         shortWait();
442                         log.println("selected child count: " +
443                                     oObj.getSelectedAccessibleChildCount());
444                         XAccessible selChild = oObj.getSelectedAccessibleChild(0);
445                         res &= (selChild != null);
446                         log.println("valid child - " + (selChild != null));
447                     } else {
448                         log.println("Child isn't selectable");
449                     }
450                 }
451             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
452                 log.println("Unexpected exception: Last relevant calls:\n " +
453                             "\toObj.selectAccessibleChild("+k+")\n" +
454                             "\toObj.getSelectedAccessibleChild(0)");
455                 e.printStackTrace(log);
456                 res = false;
457             }
458         }
459 
460         tRes.tested("getSelectedAccessibleChild()", res);
461     }
462 
463     /**
464      * Calls the method with wrong and with correct indexes.
465      * Has OK status if exceptions were thrown for the calls with
466      * the wrong indexes, if exception wasn't thrown for the call
467      * with correct index and if number of selected child was
468      * decreased after the correct call.
469      */
_deselectAccessibleChild()470     public void _deselectAccessibleChild() {
471         executeMethod("getSelectedAccessibleChild()");
472 
473         boolean res = true;
474         int selCount = oObj.getSelectedAccessibleChildCount();
475         log.println("getSelectedAccessibleChildCount():" + selCount);
476 
477         try {
478             log.println("deselectAccessibleChild(-1)");
479             oObj.deselectAccessibleChild(-1);
480             log.println("Exception was expected");
481             res = false;
482         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
483             log.println("Expected exception");
484             res &= true;
485         }
486 
487         try {
488             log.println("deselectAccessibleChild(" + (childCount + 1) + ")");
489             oObj.deselectAccessibleChild(childCount + 1);
490             log.println("Exception was expected");
491             res = false;
492         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
493             log.println("Expected exception");
494             res &= true;
495         }
496 
497         log.println("#################");
498         log.println("Selecting all accessible");
499         oObj.selectAllAccessibleChildren();
500         selCount = oObj.getSelectedAccessibleChildCount();
501         log.println("getSelectedAccessibleChildCount():" + selCount);
502 
503         if ((childCount > 0) && (selCount > 0)) {
504             try {
505                 int maxCount = chkSelectable(tEnv.getTestObject());
506 
507                 if (childCount > 100) {
508                     maxCount = 100;
509                 }
510 
511                 for (int k = 0; k < maxCount; k++) {
512                     log.println("deselectAccessibleChild(" + k + ")");
513 
514                     if (oObj.isAccessibleChildSelected(k)) {
515                         oObj.deselectAccessibleChild(k);
516                     }
517                 }
518 
519                 int newSelCount = oObj.getSelectedAccessibleChildCount();
520                 log.println("getSelectedAccessibleChildCount():" +
521                             newSelCount);
522 
523                 if (OneAlwaysSelected && (selCount == 1)) {
524                     log.println("One Child is always selected");
525                     res &= true;
526                 } else {
527                     res &= (selCount > newSelCount);
528                 }
529             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
530                 log.println("Unexpected exception");
531                 e.printStackTrace(log);
532                 res = false;
533             }
534         }
535 
536         tRes.tested("deselectAccessibleChild()", res);
537     }
538 
chkSelectable(Object Testcase)539     protected static int chkSelectable(Object Testcase) {
540         int ret = 0;
541         XAccessibleContext accCon = (XAccessibleContext) UnoRuntime.queryInterface(
542                                             XAccessibleContext.class, Testcase);
543         int cc = accCon.getAccessibleChildCount();
544 
545         if (cc > 500) {
546             return cc;
547         }
548 
549         for (int i = 0; i < cc; i++) {
550             try {
551                 if (accCon.getAccessibleChild(i).getAccessibleContext()
552                           .getAccessibleStateSet()
553                           .contains(com.sun.star.accessibility.AccessibleStateType.SELECTABLE)) {
554                     ret = ret + 1;
555                     System.out.println("Child " + i + " is selectable");
556                 }
557             } catch (com.sun.star.lang.IndexOutOfBoundsException iab) {
558             }
559         }
560 
561         return ret;
562     }
563 
isSelectable(Object Testcase, int index)564     protected static boolean isSelectable(Object Testcase, int index) {
565         XAccessibleContext accCon = (XAccessibleContext) UnoRuntime.queryInterface(
566                                             XAccessibleContext.class, Testcase);
567         boolean res = false;
568 
569         try {
570             if (accCon.getAccessibleChild(index).getAccessibleContext()
571                       .getAccessibleStateSet()
572                       .contains(com.sun.star.accessibility.AccessibleStateType.SELECTABLE)) {
573                 res = true;
574             }
575 
576             //selecting menuitems or the separator will lead to closing the menu
577             if ((accCon.getAccessibleChild(index).getAccessibleContext()
578                        .getAccessibleRole() == AccessibleRole.MENU_ITEM) ||
579                     (accCon.getAccessibleChild(index).getAccessibleContext()
580                            .getAccessibleRole() == AccessibleRole.SEPARATOR)) {
581                 res = false;
582             }
583         } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
584             System.out.println("Exception while checking for selectability");
585         }
586 
587         return res;
588     }
589 
shortWait()590     private void shortWait() {
591         try {
592             Thread.sleep(500);
593         } catch (InterruptedException ex) {
594         }
595     }
596 }
597