`,
async function (browser, accDoc) {
for (let { desc, id, action, attrs, expected, waitFor } of valueTests) {
info(desc);
let acc = findAccessibleChildByID(accDoc, id);
let onUpdate;
if (waitFor) {
onUpdate = waitForEvent(waitFor, id);
}
if (action) {
await action(browser, acc);
} else if (attrs) {
for (let { attr, value } of attrs) {
await invokeSetAttribute(browser, id, attr, value);
}
}
await onUpdate;
if (Array.isArray(expected)) {
acc.QueryInterface(nsIAccessibleValue);
await testValue(acc, ...expected);
} else {
is(acc.value, expected, `Correct value for ${prettyName(acc)}`);
}
}
},
{ iframe: true, remoteIframe: true }
);
/**
* Test caching of link URL values.
*/
addAccessibleTask(
`Test`,
async function (browser, docAcc) {
let link = findAccessibleChildByID(docAcc, "link");
is(link.value, "https://example.com/", "link initial value correct");
const textLeaf = link.firstChild;
is(textLeaf.value, "https://example.com/", "link initial value correct");
info("Changing link href");
await invokeSetAttribute(browser, "link", "href", "https://example.net/");
await untilCacheIs(
() => link.value,
"https://example.net/",
"link value correct after change"
);
info("Removing link href");
let onRecreation = waitForEvents({
expected: [
[EVENT_HIDE, link],
[EVENT_SHOW, "link"],
],
});
await invokeSetAttribute(browser, "link", "href");
await onRecreation;
link = findAccessibleChildByID(docAcc, "link");
await untilCacheIs(() => link.value, "", "link value empty after removal");
info("Setting link href");
onRecreation = waitForEvents({
expected: [
[EVENT_HIDE, link],
[EVENT_SHOW, "link"],
],
});
await invokeSetAttribute(browser, "link", "href", "https://example.com/");
await onRecreation;
link = findAccessibleChildByID(docAcc, "link");
await untilCacheIs(
() => link.value,
"https://example.com/",
"link value correct after change"
);
},
{ chrome: true, topLevel: true, iframe: true, remoteIframe: true }
);
/**
* Test caching of active state for select options - see bug 1788143.
*/
addAccessibleTask(
`
`,
async function (browser, docAcc) {
const select = findAccessibleChildByID(docAcc, "select");
is(select.value, "First", "Select initial value correct");
// Focus the combo box.
await invokeFocus(browser, "select");
// Select the second option (drop-down collapsed).
let p = waitForEvents({
expected: [
[EVENT_SELECTION, "second_option"],
[EVENT_TEXT_VALUE_CHANGE, "select"],
],
unexpected: [
stateChangeEventArgs("second_option", EXT_STATE_ACTIVE, true, true),
stateChangeEventArgs("first_option", EXT_STATE_ACTIVE, false, true),
],
});
await invokeContentTask(browser, [], () => {
content.document.getElementById("select").selectedIndex = 1;
});
await p;
is(select.value, "Second", "Select value correct after changing option");
// Expand the combobox dropdown.
p = waitForEvent(EVENT_STATE_CHANGE, "ContentSelectDropdown");
EventUtils.synthesizeKey("VK_SPACE");
await p;
p = waitForEvents({
expected: [
[EVENT_SELECTION, "first_option"],
[EVENT_TEXT_VALUE_CHANGE, "select"],
[EVENT_HIDE, "ContentSelectDropdown"],
],
unexpected: [
stateChangeEventArgs("first_option", EXT_STATE_ACTIVE, true, true),
stateChangeEventArgs("second_option", EXT_STATE_ACTIVE, false, true),
],
});
// Press the up arrow to select the first option (drop-down expanded).
// Then, press Enter to confirm the selection and close the dropdown.
// We do both of these together to unify testing across platforms, since
// events are not entirely consistent on Windows vs. Linux + macOS.
EventUtils.synthesizeKey("VK_UP");
EventUtils.synthesizeKey("VK_RETURN");
await p;
is(
select.value,
"First",
"Select value correct after changing option back"
);
},
{ chrome: true, topLevel: true, iframe: true, remoteIframe: true }
);
/**
* Test combobox values for non-editable comboboxes.
*/
addAccessibleTask(
`
value
value
value
foo
bar
testing
value
`,
async function (browser, docAcc) {
const comboDiv1 = findAccessibleChildByID(docAcc, "combo-div-1");
const comboDiv2 = findAccessibleChildByID(docAcc, "combo-div-2");
const comboDiv3 = findAccessibleChildByID(docAcc, "combo-div-3");
const comboDiv4 = findAccessibleChildByID(docAcc, "combo-div-4");
const comboInput1 = findAccessibleChildByID(docAcc, "combo-input-1");
const comboInput2 = findAccessibleChildByID(docAcc, "combo-input-2");
const comboDivSelected = findAccessibleChildByID(
docAcc,
"combo-div-selected"
);
// Text as a descendant of the combobox: included in the value.
is(comboDiv1.value, "value", "Combobox value correct");
// Text as the descendant of a listbox: excluded from the value.
is(comboDiv2.value, "", "Combobox value correct");
// Text as the descendant of some other role that includes text in name computation.
// Here, the group role contains the text node with "value" in it.
is(comboDiv3.value, "value", "Combobox value correct");
// Some descendant text included, but text descendant of a listbox excluded.
is(comboDiv4.value, "foo", "Combobox value correct");
// Combobox inputs with explicit value report that value.
is(comboInput1.value, "value", "Combobox value correct");
is(comboInput2.value, "value", "Combobox value correct");
// Combobox role with aria-selected reports correct value.
is(comboDivSelected.value, "value", "Combobox value correct");
},
{ chrome: true, iframe: true, remoteIframe: true }
);