/* 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";
// From https://learn.microsoft.com/en-us/windows/win32/api/uiautomationcore/ne-uiautomationcore-livesetting
const LiveSetting = {
Off: 0,
Polite: 1,
Assertive: 2,
};
/**
* Test the LiveSetting property.
*/
addUiaTask(
`
assertive
off
none
`,
async function testLiveSettingProp() {
await definePyVar("doc", `getDocUia()`);
is(
await runPython(`findUiaByDomId(doc, "polite").CurrentLiveSetting`),
LiveSetting.Polite,
"polite has correct LiveSetting"
);
// LiveSetting should only be exposed on the root of a live region.
// The IA2 -> UIA proxy disagrees, but:
// 1. The UIA documentation doesn't specify whether descendants should
// expose this.
// 2. Chromium only exposes it on the root. Given that live regions work in
// Chromium but not with the IA2 -> UIA proxy, it makes sense to follow
// Chromium in the absence of good documentation.
// 3. It's cheaper to expose it only on the root, since that avoids many
// ancestor walks.
if (gIsUiaEnabled) {
is(
await runPython(`findUiaByDomId(doc, "inner").CurrentLiveSetting`),
LiveSetting.Off,
"inner has correct LiveSetting"
);
}
is(
await runPython(`findUiaByDomId(doc, "assertive").CurrentLiveSetting`),
LiveSetting.Assertive,
"assertive has correct LiveSetting"
);
is(
await runPython(`findUiaByDomId(doc, "off").CurrentLiveSetting`),
LiveSetting.Off,
"off has correct LiveSetting"
);
is(
await runPython(`findUiaByDomId(doc, "output").CurrentLiveSetting`),
LiveSetting.Polite,
"output has correct LiveSetting"
);
is(
await runPython(`findUiaByDomId(doc, "none").CurrentLiveSetting`),
LiveSetting.Off,
"none has correct LiveSetting"
);
}
);
/**
* Test exposure of aria-atomic via the AriaProperties property.
*/
addUiaTask(
`
live
false
true
none
`,
async function testAtomic() {
await definePyVar("doc", `getDocUia()`);
let result = await runPython(
`findUiaByDomId(doc, "implicit").CurrentAriaProperties`
);
isnot(
result.indexOf("atomic=false"),
-1,
"AriaProperties for implicit contains atomic=false"
);
result = await runPython(
`findUiaByDomId(doc, "false").CurrentAriaProperties`
);
isnot(
result.indexOf("atomic=false"),
-1,
"AriaProperties for false contains atomic=false"
);
result = await runPython(
`findUiaByDomId(doc, "true").CurrentAriaProperties`
);
isnot(
result.indexOf("atomic=true"),
-1,
"AriaProperties for true contains atomic=true"
);
result = await runPython(
`findUiaByDomId(doc, "none").CurrentAriaProperties`
);
is(
result.indexOf("atomic"),
-1,
"AriaProperties for none doesn't contain atomic"
);
},
// The IA2 -> UIA proxy doesn't support atomic.
{ uiaEnabled: true, uiaDisabled: false }
);
/**
* Test that a live region is exposed as a control element.
*/
addUiaTask(
`
notLive
`,
async function testIsControl() {
await definePyVar("doc", `getDocUia()`);
ok(
await runPython(`findUiaByDomId(doc, "live").CurrentIsControlElement`),
"live is a control element"
);
// The IA2 -> UIA proxy gets this wrong.
if (gIsUiaEnabled) {
ok(
!(await runPython(
`findUiaByDomId(doc, "inner").CurrentIsControlElement`
)),
"inner is not a control element"
);
}
ok(
!(await runPython(
`findUiaByDomId(doc, "notLive").CurrentIsControlElement`
)),
"notLive is not a control element"
);
}
);
/**
* Test LiveRegionChanged events.
*/
addUiaTask(
`
`,
async function testLiveRegionChangedEvent(browser) {
await definePyVar("doc", `getDocUia()`);
info("Showing b");
await setUpWaitForUiaEvent("LiveRegionChanged", "live");
await invokeContentTask(browser, [], () => {
content.document.getElementById("b").hidden = false;
});
await waitForUiaEvent();
ok(true, "Got LiveRegionChanged on live");
// The c span doesn't get an Accessible, so this tests that we get an event
// when a text leaf is added directly.
info("Showing c");
await setUpWaitForUiaEvent("LiveRegionChanged", "live");
await invokeContentTask(browser, [], () => {
content.document.getElementById("c").hidden = false;
});
await waitForUiaEvent();
ok(true, "Got LiveRegionChanged on live");
info("Setting d's aria-label");
await setUpWaitForUiaEvent("LiveRegionChanged", "live");
await invokeSetAttribute(browser, "d", "aria-label", "d");
await waitForUiaEvent();
ok(true, "Got LiveRegionChanged on live");
info("Setting live textContent (new text leaf)");
await setUpWaitForUiaEvent("LiveRegionChanged", "live");
await invokeContentTask(browser, [], () => {
content.document.getElementById("live").textContent = "replaced";
});
await waitForUiaEvent();
ok(true, "Got LiveRegionChanged on live");
info("Mutating live's text node (same text leaf)");
await setUpWaitForUiaEvent("LiveRegionChanged", "live");
await invokeContentTask(browser, [], () => {
content.document.getElementById("live").firstChild.data = "again";
});
await waitForUiaEvent();
ok(true, "Got LiveRegionChanged on live");
},
// The IA2 -> UIA proxy doesn't fire LiveRegionChanged.
{ uiaEnabled: true, uiaDisabled: false }
);