no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / accessible / tests / mochitest / relations.js
blobaa956649ffdc595f8a3947c11d5317782a56a7b2
1 /* import-globals-from common.js */
3 // //////////////////////////////////////////////////////////////////////////////
4 // Constants
6 var RELATION_CONTROLLED_BY = nsIAccessibleRelation.RELATION_CONTROLLED_BY;
7 var RELATION_CONTROLLER_FOR = nsIAccessibleRelation.RELATION_CONTROLLER_FOR;
8 var RELATION_DEFAULT_BUTTON = nsIAccessibleRelation.RELATION_DEFAULT_BUTTON;
9 var RELATION_DESCRIBED_BY = nsIAccessibleRelation.RELATION_DESCRIBED_BY;
10 var RELATION_DESCRIPTION_FOR = nsIAccessibleRelation.RELATION_DESCRIPTION_FOR;
11 var RELATION_EMBEDDED_BY = nsIAccessibleRelation.RELATION_EMBEDDED_BY;
12 var RELATION_EMBEDS = nsIAccessibleRelation.RELATION_EMBEDS;
13 var RELATION_FLOWS_FROM = nsIAccessibleRelation.RELATION_FLOWS_FROM;
14 var RELATION_FLOWS_TO = nsIAccessibleRelation.RELATION_FLOWS_TO;
15 var RELATION_LABEL_FOR = nsIAccessibleRelation.RELATION_LABEL_FOR;
16 var RELATION_LABELLED_BY = nsIAccessibleRelation.RELATION_LABELLED_BY;
17 var RELATION_MEMBER_OF = nsIAccessibleRelation.RELATION_MEMBER_OF;
18 var RELATION_NODE_CHILD_OF = nsIAccessibleRelation.RELATION_NODE_CHILD_OF;
19 var RELATION_NODE_PARENT_OF = nsIAccessibleRelation.RELATION_NODE_PARENT_OF;
20 var RELATION_PARENT_WINDOW_OF = nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF;
21 var RELATION_POPUP_FOR = nsIAccessibleRelation.RELATION_POPUP_FOR;
22 var RELATION_SUBWINDOW_OF = nsIAccessibleRelation.RELATION_SUBWINDOW_OF;
23 var RELATION_CONTAINING_DOCUMENT =
24   nsIAccessibleRelation.RELATION_CONTAINING_DOCUMENT;
25 var RELATION_CONTAINING_TAB_PANE =
26   nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE;
27 var RELATION_CONTAINING_APPLICATION =
28   nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION;
29 const RELATION_DETAILS = nsIAccessibleRelation.RELATION_DETAILS;
30 const RELATION_DETAILS_FOR = nsIAccessibleRelation.RELATION_DETAILS_FOR;
31 const RELATION_ERRORMSG = nsIAccessibleRelation.RELATION_ERRORMSG;
32 const RELATION_ERRORMSG_FOR = nsIAccessibleRelation.RELATION_ERRORMSG_FOR;
33 const RELATION_LINKS_TO = nsIAccessibleRelation.RELATION_LINKS_TO;
35 // //////////////////////////////////////////////////////////////////////////////
36 // General
38 /**
39  * Test the accessible relation.
40  *
41  * @param aIdentifier          [in] identifier to get an accessible, may be ID
42  *                             attribute or DOM element or accessible object
43  * @param aRelType             [in] relation type (see constants above)
44  * @param aRelatedIdentifiers  [in] identifier or array of identifiers of
45  *                             expected related accessibles
46  */
47 function testRelation(aIdentifier, aRelType, aRelatedIdentifiers) {
48   var relation = getRelationByType(aIdentifier, aRelType);
50   var relDescr = getRelationErrorMsg(aIdentifier, aRelType);
51   var relDescrStart = getRelationErrorMsg(aIdentifier, aRelType, true);
53   if (!relation || !relation.targetsCount) {
54     if (!aRelatedIdentifiers) {
55       ok(true, "No" + relDescr);
56       return;
57     }
59     var msg =
60       relDescrStart +
61       "has no expected targets: '" +
62       prettyName(aRelatedIdentifiers) +
63       "'";
65     ok(false, msg);
66     return;
67   } else if (!aRelatedIdentifiers) {
68     ok(false, "There are unexpected targets of " + relDescr);
69     return;
70   }
72   var relatedIds =
73     aRelatedIdentifiers instanceof Array
74       ? aRelatedIdentifiers
75       : [aRelatedIdentifiers];
77   var targets = [];
78   for (let idx = 0; idx < relatedIds.length; idx++) {
79     targets.push(getAccessible(relatedIds[idx]));
80   }
82   if (targets.length != relatedIds.length) {
83     return;
84   }
86   var actualTargets = relation.getTargets();
88   // Check if all given related accessibles are targets of obtained relation.
89   for (let idx = 0; idx < targets.length; idx++) {
90     var isFound = false;
91     for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
92       if (targets[idx] == relatedAcc) {
93         isFound = true;
94         break;
95       }
96     }
98     ok(isFound, prettyName(relatedIds[idx]) + " is not a target of" + relDescr);
99   }
101   // Check if all obtained targets are given related accessibles.
102   for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
103     let idx;
104     // eslint-disable-next-line no-empty
105     for (idx = 0; idx < targets.length && relatedAcc != targets[idx]; idx++) {}
107     if (idx == targets.length) {
108       ok(
109         false,
110         "There is unexpected target" + prettyName(relatedAcc) + "of" + relDescr
111       );
112     }
113   }
117  * Test that the given accessible relations don't exist.
119  * @param aIdentifier           [in] identifier to get an accessible, may be ID
120  *                              attribute or DOM element or accessible object
121  * @param aRelType              [in] relation type (see constants above)
122  * @param aUnrelatedIdentifiers [in] identifier or array of identifiers of
123  *                              accessibles that shouldn't exist for this
124  *                              relation.
125  */
126 function testAbsentRelation(aIdentifier, aRelType, aUnrelatedIdentifiers) {
127   var relation = getRelationByType(aIdentifier, aRelType);
129   var relDescr = getRelationErrorMsg(aIdentifier, aRelType);
131   if (!aUnrelatedIdentifiers) {
132     ok(false, "No identifiers given for unrelated accessibles.");
133     return;
134   }
136   if (!relation || !relation.targetsCount) {
137     ok(true, "No relations exist.");
138     return;
139   }
141   var relatedIds =
142     aUnrelatedIdentifiers instanceof Array
143       ? aUnrelatedIdentifiers
144       : [aUnrelatedIdentifiers];
146   var targets = [];
147   for (let idx = 0; idx < relatedIds.length; idx++) {
148     targets.push(getAccessible(relatedIds[idx]));
149   }
151   if (targets.length != relatedIds.length) {
152     return;
153   }
155   var actualTargets = relation.getTargets();
157   // Any found targets that match given accessibles should be called out.
158   for (let idx = 0; idx < targets.length; idx++) {
159     var notFound = true;
160     for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
161       if (targets[idx] == relatedAcc) {
162         notFound = false;
163         break;
164       }
165     }
167     ok(notFound, prettyName(relatedIds[idx]) + " is a target of " + relDescr);
168   }
172  * Return related accessible for the given relation type.
174  * @param aIdentifier  [in] identifier to get an accessible, may be ID attribute
175  *                     or DOM element or accessible object
176  * @param aRelType     [in] relation type (see constants above)
177  */
178 function getRelationByType(aIdentifier, aRelType) {
179   var acc = getAccessible(aIdentifier);
180   if (!acc) {
181     return null;
182   }
184   var relation = null;
185   try {
186     relation = acc.getRelationByType(aRelType);
187   } catch (e) {
188     ok(false, "Can't get" + getRelationErrorMsg(aIdentifier, aRelType));
189   }
191   return relation;
194 // //////////////////////////////////////////////////////////////////////////////
195 // Private implementation details
197 function getRelationErrorMsg(aIdentifier, aRelType, aIsStartSentence) {
198   var relStr = relationTypeToString(aRelType);
199   var msg = aIsStartSentence ? "Relation of '" : " relation of '";
200   msg += relStr + "' type for '" + prettyName(aIdentifier) + "'";
201   msg += aIsStartSentence ? " " : ".";
203   return msg;