mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 1787284: [Part 4] Core tests for MEMBER_OF relation r=eeejay
Depends on D159119 Differential Revision: https://phabricator.services.mozilla.com/D159120
This commit is contained in:
parent
5ba1794a07
commit
b0dedce119
@ -17,7 +17,7 @@ support-files =
|
||||
|
||||
# Caching tests
|
||||
[browser_caching_actions.js]
|
||||
skip-if =
|
||||
skip-if =
|
||||
(apple_catalina || apple_silicon) && !debug # Bug 1779541
|
||||
[browser_caching_attributes.js]
|
||||
[browser_caching_description.js]
|
||||
@ -27,6 +27,7 @@ skip-if = os != 'win'
|
||||
[browser_caching_name.js]
|
||||
skip-if = (os == "linux" && bits == 64) || (debug && os == "mac") || (debug && os == "win") #Bug 1388256
|
||||
[browser_caching_relations.js]
|
||||
[browser_caching_relations_002.js]
|
||||
[browser_caching_states.js]
|
||||
[browser_caching_table.js]
|
||||
[browser_caching_text.js]
|
||||
|
@ -5,9 +5,6 @@
|
||||
"use strict";
|
||||
requestLongerTimeout(2);
|
||||
|
||||
/* import-globals-from ../../mochitest/relations.js */
|
||||
loadScripts({ name: "relations.js", dir: MOCHITESTS_DIR });
|
||||
|
||||
/**
|
||||
* A test specification that has the following format:
|
||||
* [
|
||||
@ -23,176 +20,6 @@ const attrRelationsSpec = [
|
||||
["aria-flowto", RELATION_FLOWS_TO, RELATION_FLOWS_FROM],
|
||||
];
|
||||
|
||||
/**
|
||||
* Test the accessible relation.
|
||||
*
|
||||
* @param identifier [in] identifier to get an accessible, may be ID
|
||||
* attribute or DOM element or accessible object
|
||||
* @param relType [in] relation type (see constants above)
|
||||
* @param relatedIdentifiers [in] identifier or array of identifiers of
|
||||
* expected related accessibles
|
||||
*/
|
||||
async function testCachedRelation(identifier, relType, relatedIdentifiers) {
|
||||
const relDescr = getRelationErrorMsg(identifier, relType);
|
||||
const relDescrStart = getRelationErrorMsg(identifier, relType, true);
|
||||
info(`Testing ${relDescr}`);
|
||||
|
||||
if (!relatedIdentifiers) {
|
||||
await untilCacheOk(function() {
|
||||
let r = getRelationByType(identifier, relType);
|
||||
if (r) {
|
||||
info(`Fetched ${r.targetsCount} relations from cache`);
|
||||
} else {
|
||||
info("Could not fetch relations");
|
||||
}
|
||||
return r && !r.targetsCount;
|
||||
}, relDescrStart + " has no targets, as expected");
|
||||
return;
|
||||
}
|
||||
|
||||
const relatedIds =
|
||||
relatedIdentifiers instanceof Array
|
||||
? relatedIdentifiers
|
||||
: [relatedIdentifiers];
|
||||
await untilCacheOk(function() {
|
||||
let r = getRelationByType(identifier, relType);
|
||||
if (r) {
|
||||
info(
|
||||
`Fetched ${r.targetsCount} relations from cache, looking for ${relatedIds.length}`
|
||||
);
|
||||
} else {
|
||||
info("Could not fetch relations");
|
||||
}
|
||||
|
||||
return r && r.targetsCount == relatedIds.length;
|
||||
}, "Found correct number of expected relations");
|
||||
|
||||
let targets = [];
|
||||
for (let idx = 0; idx < relatedIds.length; idx++) {
|
||||
targets.push(getAccessible(relatedIds[idx]));
|
||||
}
|
||||
|
||||
if (targets.length != relatedIds.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
await untilCacheOk(function() {
|
||||
const relation = getRelationByType(identifier, relType);
|
||||
const actualTargets = relation ? relation.getTargets() : null;
|
||||
if (!actualTargets) {
|
||||
info("Could not fetch relations");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if all given related accessibles are targets of obtained relation.
|
||||
for (let idx = 0; idx < targets.length; idx++) {
|
||||
let isFound = false;
|
||||
for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
|
||||
if (targets[idx] == relatedAcc) {
|
||||
isFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFound) {
|
||||
info(
|
||||
prettyName(relatedIds[idx]) +
|
||||
" could not be found in relation: " +
|
||||
relDescr
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}, "All given related accessibles are targets of fetched relation.");
|
||||
|
||||
await untilCacheOk(function() {
|
||||
const relation = getRelationByType(identifier, relType);
|
||||
const actualTargets = relation ? relation.getTargets() : null;
|
||||
if (!actualTargets) {
|
||||
info("Could not fetch relations");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if all obtained targets are given related accessibles.
|
||||
for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
|
||||
let wasFound = false;
|
||||
for (let idx = 0; idx < targets.length; idx++) {
|
||||
if (relatedAcc == targets[idx]) {
|
||||
wasFound = true;
|
||||
}
|
||||
}
|
||||
if (!wasFound) {
|
||||
info(
|
||||
prettyName(relatedAcc) +
|
||||
" was found, but shouldn't be in relation: " +
|
||||
relDescr
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, "No unexpected targets found.");
|
||||
}
|
||||
|
||||
async function testRelated(
|
||||
browser,
|
||||
accDoc,
|
||||
attr,
|
||||
hostRelation,
|
||||
dependantRelation
|
||||
) {
|
||||
let host = findAccessibleChildByID(accDoc, "host");
|
||||
let dependant1 = findAccessibleChildByID(accDoc, "dependant1");
|
||||
let dependant2 = findAccessibleChildByID(accDoc, "dependant2");
|
||||
|
||||
/**
|
||||
* Test data has the format of:
|
||||
* {
|
||||
* desc {String} description for better logging
|
||||
* attrs {?Array} an optional list of attributes to update
|
||||
* expected {Array} expected relation values for dependant1, dependant2
|
||||
* and host respectively.
|
||||
* }
|
||||
*/
|
||||
const tests = [
|
||||
{
|
||||
desc: "No attribute",
|
||||
expected: [null, null, null],
|
||||
},
|
||||
{
|
||||
desc: "Set attribute",
|
||||
attrs: [{ key: attr, value: "dependant1" }],
|
||||
expected: [host, null, dependant1],
|
||||
},
|
||||
{
|
||||
desc: "Change attribute",
|
||||
attrs: [{ key: attr, value: "dependant2" }],
|
||||
expected: [null, host, dependant2],
|
||||
},
|
||||
{
|
||||
desc: "Remove attribute",
|
||||
attrs: [{ key: attr }],
|
||||
expected: [null, null, null],
|
||||
},
|
||||
];
|
||||
|
||||
for (let { desc, attrs, expected } of tests) {
|
||||
info(desc);
|
||||
|
||||
if (attrs) {
|
||||
for (let { key, value } of attrs) {
|
||||
await invokeSetAttribute(browser, "host", key, value);
|
||||
}
|
||||
}
|
||||
|
||||
await testCachedRelation(dependant1, dependantRelation, expected[0]);
|
||||
await testCachedRelation(dependant2, dependantRelation, expected[1]);
|
||||
await testCachedRelation(host, hostRelation, expected[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test caching of relations between accessible objects.
|
||||
*/
|
||||
|
@ -0,0 +1,83 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test MEMBER_OF relation caching on HTML radio buttons
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<input type="radio" id="r1">I have no name<br>
|
||||
<input type="radio" id="r2">I also have no name<br>
|
||||
<input type="radio" id="r3" name="n">I have a name<br>
|
||||
<input type="radio" id="r4" name="a">I have a different name<br>
|
||||
<fieldset role="radiogroup">
|
||||
<input type="radio" id="r5" name="n">I have an already used name
|
||||
and am in a different part of the tree
|
||||
<input type="radio" id="r6" name="r">I have a different name but am
|
||||
in the same group
|
||||
</fieldset>`,
|
||||
async function(browser, accDoc) {
|
||||
const r1 = findAccessibleChildByID(accDoc, "r1");
|
||||
const r2 = findAccessibleChildByID(accDoc, "r2");
|
||||
const r3 = findAccessibleChildByID(accDoc, "r3");
|
||||
const r4 = findAccessibleChildByID(accDoc, "r4");
|
||||
const r5 = findAccessibleChildByID(accDoc, "r5");
|
||||
const r6 = findAccessibleChildByID(accDoc, "r6");
|
||||
|
||||
await testCachedRelation(r1, RELATION_MEMBER_OF, null);
|
||||
await testCachedRelation(r2, RELATION_MEMBER_OF, null);
|
||||
await testCachedRelation(r3, RELATION_MEMBER_OF, [r3, r5]);
|
||||
await testCachedRelation(r4, RELATION_MEMBER_OF, r4);
|
||||
await testCachedRelation(r5, RELATION_MEMBER_OF, [r3, r5]);
|
||||
await testCachedRelation(r6, RELATION_MEMBER_OF, r6);
|
||||
|
||||
await invokeContentTask(browser, [], () => {
|
||||
content.document.getElementById("r5").name = "a";
|
||||
});
|
||||
|
||||
await testCachedRelation(r3, RELATION_MEMBER_OF, r3);
|
||||
await testCachedRelation(r4, RELATION_MEMBER_OF, [r5, r4]);
|
||||
await testCachedRelation(r5, RELATION_MEMBER_OF, [r5, r4]);
|
||||
},
|
||||
{ chrome: true, iframe: true, remoteIframe: true }
|
||||
);
|
||||
|
||||
/*
|
||||
* Test MEMBER_OF relation caching on aria radio buttons
|
||||
*/
|
||||
addAccessibleTask(
|
||||
`
|
||||
<div role="radio" id="r1">I have no radio group</div><br>
|
||||
<fieldset role="radiogroup" id="fs">
|
||||
<div role="radio" id="r2">hello</div><br>
|
||||
<div role="radio" id="r3">world</div><br>
|
||||
</fieldset>`,
|
||||
async function(browser, accDoc) {
|
||||
const r1 = findAccessibleChildByID(accDoc, "r1");
|
||||
const r2 = findAccessibleChildByID(accDoc, "r2");
|
||||
let r3 = findAccessibleChildByID(accDoc, "r3");
|
||||
|
||||
await testCachedRelation(r1, RELATION_MEMBER_OF, null);
|
||||
await testCachedRelation(r2, RELATION_MEMBER_OF, [r2, r3]);
|
||||
await testCachedRelation(r3, RELATION_MEMBER_OF, [r2, r3]);
|
||||
const r = waitForEvent(EVENT_INNER_REORDER, "fs");
|
||||
await invokeContentTask(browser, [], () => {
|
||||
let innerRadio = content.document.getElementById("r3");
|
||||
content.document.body.appendChild(innerRadio);
|
||||
});
|
||||
await r;
|
||||
|
||||
r3 = findAccessibleChildByID(accDoc, "r3");
|
||||
await testCachedRelation(r1, RELATION_MEMBER_OF, null);
|
||||
await testCachedRelation(r2, RELATION_MEMBER_OF, r2);
|
||||
await testCachedRelation(r3, RELATION_MEMBER_OF, null);
|
||||
},
|
||||
{
|
||||
chrome: true,
|
||||
iframe: true,
|
||||
remoteIframe: true,
|
||||
}
|
||||
);
|
@ -4,6 +4,8 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
/* exported testCachedRelation, testRelated */
|
||||
|
||||
// Load the shared-head file first.
|
||||
/* import-globals-from ../shared-head.js */
|
||||
Services.scriptloader.loadSubScript(
|
||||
@ -12,8 +14,180 @@ Services.scriptloader.loadSubScript(
|
||||
);
|
||||
|
||||
// Loading and common.js from accessible/tests/mochitest/ for all tests, as
|
||||
// well as promisified-events.js.
|
||||
// well as promisified-events.js and relations.js.
|
||||
/* import-globals-from ../../mochitest/relations.js */
|
||||
loadScripts(
|
||||
{ name: "common.js", dir: MOCHITESTS_DIR },
|
||||
{ name: "promisified-events.js", dir: MOCHITESTS_DIR }
|
||||
{ name: "promisified-events.js", dir: MOCHITESTS_DIR },
|
||||
{ name: "relations.js", dir: MOCHITESTS_DIR }
|
||||
);
|
||||
|
||||
/**
|
||||
* Test the accessible relation.
|
||||
*
|
||||
* @param identifier [in] identifier to get an accessible, may be ID
|
||||
* attribute or DOM element or accessible object
|
||||
* @param relType [in] relation type (see constants above)
|
||||
* @param relatedIdentifiers [in] identifier or array of identifiers of
|
||||
* expected related accessibles
|
||||
*/
|
||||
async function testCachedRelation(identifier, relType, relatedIdentifiers) {
|
||||
const relDescr = getRelationErrorMsg(identifier, relType);
|
||||
const relDescrStart = getRelationErrorMsg(identifier, relType, true);
|
||||
info(`Testing ${relDescr}`);
|
||||
|
||||
if (!relatedIdentifiers) {
|
||||
await untilCacheOk(function() {
|
||||
let r = getRelationByType(identifier, relType);
|
||||
if (r) {
|
||||
info(`Fetched ${r.targetsCount} relations from cache`);
|
||||
} else {
|
||||
info("Could not fetch relations");
|
||||
}
|
||||
return r && !r.targetsCount;
|
||||
}, relDescrStart + " has no targets, as expected");
|
||||
return;
|
||||
}
|
||||
|
||||
const relatedIds =
|
||||
relatedIdentifiers instanceof Array
|
||||
? relatedIdentifiers
|
||||
: [relatedIdentifiers];
|
||||
await untilCacheOk(function() {
|
||||
let r = getRelationByType(identifier, relType);
|
||||
if (r) {
|
||||
info(
|
||||
`Fetched ${r.targetsCount} relations from cache, looking for ${relatedIds.length}`
|
||||
);
|
||||
} else {
|
||||
info("Could not fetch relations");
|
||||
}
|
||||
|
||||
return r && r.targetsCount == relatedIds.length;
|
||||
}, "Found correct number of expected relations");
|
||||
|
||||
let targets = [];
|
||||
for (let idx = 0; idx < relatedIds.length; idx++) {
|
||||
targets.push(getAccessible(relatedIds[idx]));
|
||||
}
|
||||
|
||||
if (targets.length != relatedIds.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
await untilCacheOk(function() {
|
||||
const relation = getRelationByType(identifier, relType);
|
||||
const actualTargets = relation ? relation.getTargets() : null;
|
||||
if (!actualTargets) {
|
||||
info("Could not fetch relations");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if all given related accessibles are targets of obtained relation.
|
||||
for (let idx = 0; idx < targets.length; idx++) {
|
||||
let isFound = false;
|
||||
for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
|
||||
if (targets[idx] == relatedAcc) {
|
||||
isFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFound) {
|
||||
info(
|
||||
prettyName(relatedIds[idx]) +
|
||||
" could not be found in relation: " +
|
||||
relDescr
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}, "All given related accessibles are targets of fetched relation.");
|
||||
|
||||
await untilCacheOk(function() {
|
||||
const relation = getRelationByType(identifier, relType);
|
||||
const actualTargets = relation ? relation.getTargets() : null;
|
||||
if (!actualTargets) {
|
||||
info("Could not fetch relations");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if all obtained targets are given related accessibles.
|
||||
for (let relatedAcc of actualTargets.enumerate(Ci.nsIAccessible)) {
|
||||
let wasFound = false;
|
||||
for (let idx = 0; idx < targets.length; idx++) {
|
||||
if (relatedAcc == targets[idx]) {
|
||||
wasFound = true;
|
||||
}
|
||||
}
|
||||
if (!wasFound) {
|
||||
info(
|
||||
prettyName(relatedAcc) +
|
||||
" was found, but shouldn't be in relation: " +
|
||||
relDescr
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, "No unexpected targets found.");
|
||||
}
|
||||
|
||||
async function testRelated(
|
||||
browser,
|
||||
accDoc,
|
||||
attr,
|
||||
hostRelation,
|
||||
dependantRelation
|
||||
) {
|
||||
let host = findAccessibleChildByID(accDoc, "host");
|
||||
let dependant1 = findAccessibleChildByID(accDoc, "dependant1");
|
||||
let dependant2 = findAccessibleChildByID(accDoc, "dependant2");
|
||||
|
||||
/**
|
||||
* Test data has the format of:
|
||||
* {
|
||||
* desc {String} description for better logging
|
||||
* attrs {?Array} an optional list of attributes to update
|
||||
* expected {Array} expected relation values for dependant1, dependant2
|
||||
* and host respectively.
|
||||
* }
|
||||
*/
|
||||
const tests = [
|
||||
{
|
||||
desc: "No attribute",
|
||||
expected: [null, null, null],
|
||||
},
|
||||
{
|
||||
desc: "Set attribute",
|
||||
attrs: [{ key: attr, value: "dependant1" }],
|
||||
expected: [host, null, dependant1],
|
||||
},
|
||||
{
|
||||
desc: "Change attribute",
|
||||
attrs: [{ key: attr, value: "dependant2" }],
|
||||
expected: [null, host, dependant2],
|
||||
},
|
||||
{
|
||||
desc: "Remove attribute",
|
||||
attrs: [{ key: attr }],
|
||||
expected: [null, null, null],
|
||||
},
|
||||
];
|
||||
|
||||
for (let { desc, attrs, expected } of tests) {
|
||||
info(desc);
|
||||
|
||||
if (attrs) {
|
||||
for (let { key, value } of attrs) {
|
||||
await invokeSetAttribute(browser, "host", key, value);
|
||||
}
|
||||
}
|
||||
|
||||
await testCachedRelation(dependant1, dependantRelation, expected[0]);
|
||||
await testCachedRelation(dependant2, dependantRelation, expected[1]);
|
||||
await testCachedRelation(host, hostRelation, expected[2]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user