/* 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";
/* import-globals-from ../../mochitest/states.js */
loadScripts({ name: "states.js", dir: MOCHITESTS_DIR });
ChromeUtils.defineESModuleGetters(this, {
PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs",
});
/**
* Test rotor with heading
*/
addAccessibleTask(
`
hello world goodbye`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXHeadingSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const headingCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(2, headingCount, "Found two headings");
const headings = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const hello = getNativeInterface(accDoc, "hello");
const world = getNativeInterface(accDoc, "world");
is(
hello.getAttributeValue("AXTitle"),
headings[0].getAttributeValue("AXTitle"),
"Found correct first heading"
);
is(
world.getAttributeValue("AXTitle"),
headings[1].getAttributeValue("AXTitle"),
"Found correct second heading"
);
}
);
/**
* Test rotor with heading and empty search text
*/
addAccessibleTask(
`hello world goodbye`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXHeadingSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
AXSearchText: "",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const headingCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(headingCount, 2, "Found two headings");
const headings = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const hello = getNativeInterface(accDoc, "hello");
const world = getNativeInterface(accDoc, "world");
is(
headings[0].getAttributeValue("AXTitle"),
hello.getAttributeValue("AXTitle"),
"Found correct first heading"
);
is(
headings[1].getAttributeValue("AXTitle"),
world.getAttributeValue("AXTitle"),
"Found correct second heading"
);
}
);
/**
* Test rotor with articles
*/
addAccessibleTask(
`
Google Chrome
Google Chrome is a web browser developed by Google, released in 2008. Chrome is the world's most popular web browser today!
Mozilla Firefox
Mozilla Firefox is an open-source web browser developed by Mozilla. Firefox has been the second most popular web browser since January, 2018.
Microsoft Edge
Microsoft Edge is a web browser developed by Microsoft, released in 2015. Microsoft Edge replaced Internet Explorer.
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXArticleSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const articleCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(3, articleCount, "Found three articles");
const articles = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const google = getNativeInterface(accDoc, "google");
const moz = getNativeInterface(accDoc, "moz");
const microsoft = getNativeInterface(accDoc, "microsoft");
is(
google.getAttributeValue("AXTitle"),
articles[0].getAttributeValue("AXTitle"),
"Found correct first article"
);
is(
moz.getAttributeValue("AXTitle"),
articles[1].getAttributeValue("AXTitle"),
"Found correct second article"
);
is(
microsoft.getAttributeValue("AXTitle"),
articles[2].getAttributeValue("AXTitle"),
"Found correct third article"
);
}
);
/**
* Test rotor with tables
*/
addAccessibleTask(
`
Shape
Color
Do I like it?
Triangle
Green
No
Square
Red
Yes
Grocery Item
Quantity
Onions
2
Yogurt
1
Spinach
1
Cherries
12
Carrots
5
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXTableSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const tableCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(4, tableCount, "Found four tables");
const tables = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const shapes = getNativeInterface(accDoc, "shapes");
const food = getNativeInterface(accDoc, "food");
const ariaTable = getNativeInterface(accDoc, "ariaTable");
const grid = getNativeInterface(accDoc, "grid");
is(
shapes.getAttributeValue("AXColumnCount"),
tables[0].getAttributeValue("AXColumnCount"),
"Found correct first table"
);
is(
food.getAttributeValue("AXColumnCount"),
tables[1].getAttributeValue("AXColumnCount"),
"Found correct second table"
);
is(
ariaTable.getAttributeValue("AXColumnCount"),
tables[2].getAttributeValue("AXColumnCount"),
"Found correct third table"
);
is(
grid.getAttributeValue("AXColumnCount"),
tables[3].getAttributeValue("AXColumnCount"),
"Found correct fourth table"
);
}
);
/**
* Test rotor with landmarks
*/
addAccessibleTask(
`
I am a link in a nav
I am some text in a main element
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXLandmarkSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const landmarkCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(4, landmarkCount, "Found four landmarks");
const landmarks = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const header = getNativeInterface(accDoc, "header");
const nav = getNativeInterface(accDoc, "nav");
const main = getNativeInterface(accDoc, "main");
const footer = getNativeInterface(accDoc, "footer");
is(
header.getAttributeValue("AXSubrole"),
landmarks[0].getAttributeValue("AXSubrole"),
"Found correct first landmark"
);
is(
nav.getAttributeValue("AXSubrole"),
landmarks[1].getAttributeValue("AXSubrole"),
"Found correct second landmark"
);
is(
main.getAttributeValue("AXSubrole"),
landmarks[2].getAttributeValue("AXSubrole"),
"Found correct third landmark"
);
is(
footer.getAttributeValue("AXSubrole"),
landmarks[3].getAttributeValue("AXSubrole"),
"Found correct fourth landmark"
);
}
);
/**
* Test rotor with aria landmarks
*/
addAccessibleTask(
`
This is a heading within a banner
I am some text in a main element
Heading in contentinfo
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXLandmarkSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const landmarkCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(4, landmarkCount, "Found four landmarks");
const landmarks = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const banner = getNativeInterface(accDoc, "banner");
const nav = getNativeInterface(accDoc, "nav");
const main = getNativeInterface(accDoc, "main");
const contentinfo = getNativeInterface(accDoc, "contentinfo");
is(
banner.getAttributeValue("AXSubrole"),
landmarks[0].getAttributeValue("AXSubrole"),
"Found correct first landmark"
);
is(
nav.getAttributeValue("AXSubrole"),
landmarks[1].getAttributeValue("AXSubrole"),
"Found correct second landmark"
);
is(
main.getAttributeValue("AXSubrole"),
landmarks[2].getAttributeValue("AXSubrole"),
"Found correct third landmark"
);
is(
contentinfo.getAttributeValue("AXSubrole"),
landmarks[3].getAttributeValue("AXSubrole"),
"Found correct fourth landmark"
);
}
);
/**
* Test rotor with buttons
*/
addAccessibleTask(
`
hello world
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXButtonSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const buttonCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(2, buttonCount, "Found two buttons");
const buttons = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const button = getNativeInterface(accDoc, "button");
const input = getNativeInterface(accDoc, "input");
is(
button.getAttributeValue("AXRole"),
buttons[0].getAttributeValue("AXRole"),
"Found correct button"
);
is(
input.getAttributeValue("AXRole"),
buttons[1].getAttributeValue("AXRole"),
"Found correct input button"
);
}
);
/**
* Test rotor with heading
*/
addAccessibleTask(
`hello world goodbye`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXHeadingSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const headingCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(2, headingCount, "Found two headings");
const headings = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const hello = getNativeInterface(accDoc, "hello");
const world = getNativeInterface(accDoc, "world");
is(
hello.getAttributeValue("AXTitle"),
headings[0].getAttributeValue("AXTitle"),
"Found correct first heading"
);
is(
world.getAttributeValue("AXTitle"),
headings[1].getAttributeValue("AXTitle"),
"Found correct second heading"
);
}
);
/**
* Test rotor with buttons
*/
addAccessibleTask(
`
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXControlSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const controlsCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(5, controlsCount, "Found 5 controls");
const controls = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const button1 = getNativeInterface(accDoc, "button1");
const submit = getNativeInterface(accDoc, "submit");
const image = getNativeInterface(accDoc, "image");
const reset = getNativeInterface(accDoc, "reset");
const button2 = getNativeInterface(accDoc, "button2");
is(
button1.getAttributeValue("AXTitle"),
controls[0].getAttributeValue("AXTitle"),
"Found correct first control"
);
is(
submit.getAttributeValue("AXTitle"),
controls[1].getAttributeValue("AXTitle"),
"Found correct second control"
);
is(
image.getAttributeValue("AXTitle"),
controls[2].getAttributeValue("AXTitle"),
"Found correct third control"
);
is(
reset.getAttributeValue("AXTitle"),
controls[3].getAttributeValue("AXTitle"),
"Found correct third control"
);
is(
button2.getAttributeValue("AXTitle"),
controls[4].getAttributeValue("AXTitle"),
"Found correct third control"
);
}
);
/**
* Test rotor with inputs
*/
addAccessibleTask(
`
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXControlSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const controlsCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(13, controlsCount, "Found 13 controls");
// the extra controls here come from our time control
// we can't filter out its internal buttons/incrementors
// like we do with the date entry because the time entry
// doesn't have its own specific role -- its just a grouping.
const controls = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const text = getNativeInterface(accDoc, "text");
const implText = getNativeInterface(accDoc, "implText");
const textarea = getNativeInterface(accDoc, "textarea");
const tel = getNativeInterface(accDoc, "tel");
const url = getNativeInterface(accDoc, "url");
const email = getNativeInterface(accDoc, "email");
const password = getNativeInterface(accDoc, "password");
const month = getNativeInterface(accDoc, "month");
const week = getNativeInterface(accDoc, "week");
const number = getNativeInterface(accDoc, "number");
const range = getNativeInterface(accDoc, "range");
const toCheck = [
text,
implText,
textarea,
tel,
url,
email,
password,
month,
week,
number,
range,
];
for (let i = 0; i < toCheck.length; i++) {
is(
toCheck[i].getAttributeValue("AXValue"),
controls[i].getAttributeValue("AXValue"),
"Found correct input control"
);
}
const date = getNativeInterface(accDoc, "date");
const time = getNativeInterface(accDoc, "time");
is(
date.getAttributeValue("AXRole"),
controls[11].getAttributeValue("AXRole"),
"Found corrent date editor"
);
is(
time.getAttributeValue("AXRole"),
controls[12].getAttributeValue("AXRole"),
"Found corrent time editor"
);
}
);
/**
* Test rotor with groupings
*/
addAccessibleTask(
`
Radios
Radio 1
Radio 2
Checkboxes
Checkbox 1
Checkbox 2
Switches
Switch 1
Switch 2
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXControlSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const controlsCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(9, controlsCount, "Found 9 controls");
const controls = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const radios = getNativeInterface(accDoc, "radios");
const radio1 = getNativeInterface(accDoc, "radio1");
const radio2 = getNativeInterface(accDoc, "radio2");
is(
radios.getAttributeValue("AXRole"),
controls[0].getAttributeValue("AXRole"),
"Found correct group of radios"
);
is(
radio1.getAttributeValue("AXRole"),
controls[1].getAttributeValue("AXRole"),
"Found correct radio 1"
);
is(
radio2.getAttributeValue("AXRole"),
controls[2].getAttributeValue("AXRole"),
"Found correct radio 2"
);
const checkboxes = getNativeInterface(accDoc, "checkboxes");
const checkbox1 = getNativeInterface(accDoc, "checkbox1");
const checkbox2 = getNativeInterface(accDoc, "checkbox2");
is(
checkboxes.getAttributeValue("AXRole"),
controls[3].getAttributeValue("AXRole"),
"Found correct group of checkboxes"
);
is(
checkbox1.getAttributeValue("AXRole"),
controls[4].getAttributeValue("AXRole"),
"Found correct checkbox 1"
);
is(
checkbox2.getAttributeValue("AXRole"),
controls[5].getAttributeValue("AXRole"),
"Found correct checkbox 2"
);
const switches = getNativeInterface(accDoc, "switches");
const switch1 = getNativeInterface(accDoc, "switch1");
const switch2 = getNativeInterface(accDoc, "switch2");
is(
switches.getAttributeValue("AXRole"),
controls[6].getAttributeValue("AXRole"),
"Found correct group of switches"
);
is(
switch1.getAttributeValue("AXRole"),
controls[7].getAttributeValue("AXRole"),
"Found correct switch 1"
);
is(
switch2.getAttributeValue("AXRole"),
controls[8].getAttributeValue("AXRole"),
"Found correct switch 2"
);
}
);
/**
* Test rotor with misc controls
*/
addAccessibleTask(
`
Hello
world
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXControlSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const controlsCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(4, controlsCount, "Found 4 controls");
const controls = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const spin = getNativeInterface(accDoc, "spinbutton");
const details = getNativeInterface(accDoc, "details");
const tree = getNativeInterface(accDoc, "tree");
const buttonMenu = getNativeInterface(accDoc, "buttonMenu");
is(
spin.getAttributeValue("AXRole"),
controls[0].getAttributeValue("AXRole"),
"Found correct spinbutton"
);
is(
details.getAttributeValue("AXRole"),
controls[1].getAttributeValue("AXRole"),
"Found correct details element"
);
is(
tree.getAttributeValue("AXRole"),
controls[2].getAttributeValue("AXRole"),
"Found correct tree"
);
is(
buttonMenu.getAttributeValue("AXRole"),
controls[3].getAttributeValue("AXRole"),
"Found correct button menu"
);
}
);
/**
* Test rotor with links
*/
addAccessibleTask(
`
empty link
Example link
link without href
`,
async (browser, accDoc) => {
let searchPred = {
AXSearchKey: "AXLinkSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
let linkCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(2, linkCount, "Found two links");
let links = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const empty = getNativeInterface(accDoc, "empty");
const href = getNativeInterface(accDoc, "href");
is(
empty.getAttributeValue("AXTitle"),
links[0].getAttributeValue("AXTitle"),
"Found correct first link"
);
is(
href.getAttributeValue("AXTitle"),
links[1].getAttributeValue("AXTitle"),
"Found correct second link"
);
// unvisited links
searchPred = {
AXSearchKey: "AXUnvisitedLinkSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
linkCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(2, linkCount, "Found two links");
links = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(
empty.getAttributeValue("AXTitle"),
links[0].getAttributeValue("AXTitle"),
"Found correct first link"
);
is(
href.getAttributeValue("AXTitle"),
links[1].getAttributeValue("AXTitle"),
"Found correct second link"
);
// visited links
let stateChanged = waitForEvent(EVENT_STATE_CHANGE, "href");
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
await PlacesTestUtils.addVisits(["http://www.example.com/"]);
await stateChanged;
searchPred = {
AXSearchKey: "AXVisitedLinkSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
linkCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(1, linkCount, "Found one link");
links = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(
href.getAttributeValue("AXTitle"),
links[0].getAttributeValue("AXTitle"),
"Found correct visited link"
);
// Ensure history is cleared before running again
await PlacesUtils.history.clear();
}
);
/*
* Test AXAnyTypeSearchKey with root group
*/
addAccessibleTask(
`hello world goodbye`,
(browser, accDoc) => {
let searchPred = {
AXSearchKey: "AXAnyTypeSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: 1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
let results = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(results.length, 1, "One result for root group");
is(
results[0].getAttributeValue("AXIdentifier"),
"root-group",
"Is generated root group"
);
searchPred.AXStartElement = results[0];
results = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(results.length, 0, "No more results past root group");
searchPred.AXDirection = "AXDirectionPrevious";
results = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(
results.length,
0,
"Searching backwards from root group should yield no results"
);
const rootGroup = webArea.getAttributeValue("AXChildren")[0];
is(
rootGroup.getAttributeValue("AXIdentifier"),
"root-group",
"Is generated root group"
);
searchPred = {
AXSearchKey: "AXAnyTypeSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: 1,
AXDirection: "AXDirectionNext",
};
results = rootGroup.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(
results[0].getAttributeValue("AXRole"),
"AXHeading",
"Is first heading child"
);
}
);
/**
* Test rotor with checkboxes
*/
addAccessibleTask(
`
Checkboxes
Checkbox 1
Checkbox 2
Checkbox 3
Checkbox 4
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXCheckBoxSearchKey",
AXImmediateDescendantsOnly: 0,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const checkboxCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(4, checkboxCount, "Found 4 checkboxes");
const checkboxes = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const checkbox1 = getNativeInterface(accDoc, "checkbox1");
const checkbox2 = getNativeInterface(accDoc, "checkbox2");
const checkbox3 = getNativeInterface(accDoc, "checkbox3");
const checkbox4 = getNativeInterface(accDoc, "checkbox4");
is(
checkbox1.getAttributeValue("AXValue"),
checkboxes[0].getAttributeValue("AXValue"),
"Found correct checkbox 1"
);
is(
checkbox2.getAttributeValue("AXValue"),
checkboxes[1].getAttributeValue("AXValue"),
"Found correct checkbox 2"
);
is(
checkbox3.getAttributeValue("AXValue"),
checkboxes[2].getAttributeValue("AXValue"),
"Found correct checkbox 3"
);
is(
checkbox4.getAttributeValue("AXValue"),
checkboxes[3].getAttributeValue("AXValue"),
"Found correct checkbox 4"
);
}
);
/**
* Test rotor with radiogroups
*/
addAccessibleTask(
`
some radio buttons
Radio 1
Radio 2
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXRadioGroupSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const radiogroupCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(1, radiogroupCount, "Found 1 radio group");
const controls = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const radios = getNativeInterface(accDoc, "radios");
is(
radios.getAttributeValue("AXDescription"),
controls[0].getAttributeValue("AXDescription"),
"Found correct group of radios"
);
}
);
/*
* Test rotor with inputs
*/
addAccessibleTask(
`
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXTextFieldSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const textfieldCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(9, textfieldCount, "Found 9 fields");
const fields = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const text = getNativeInterface(accDoc, "text");
const implText = getNativeInterface(accDoc, "implText");
const textarea = getNativeInterface(accDoc, "textarea");
const tel = getNativeInterface(accDoc, "tel");
const url = getNativeInterface(accDoc, "url");
const email = getNativeInterface(accDoc, "email");
const password = getNativeInterface(accDoc, "password");
const month = getNativeInterface(accDoc, "month");
const week = getNativeInterface(accDoc, "week");
const toCheck = [
text,
implText,
textarea,
tel,
url,
email,
password,
month,
week,
];
for (let i = 0; i < toCheck.length; i++) {
is(
toCheck[i].getAttributeValue("AXValue"),
fields[i].getAttributeValue("AXValue"),
"Found correct input control"
);
}
}
);
/**
* Test rotor with static text
*/
addAccessibleTask(
`
Hello I am a heading
This is some regular text.this is some paragraph text
This is a list:
List item one
List item two
This is a link
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXStaticTextSearchKey",
AXImmediateDescendants: 0,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const textCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(7, textCount, "Found 7 pieces of text");
const text = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(
"Hello I am a heading",
text[0].getAttributeValue("AXValue"),
"Found correct text node for heading"
);
is(
"This is some regular text.",
text[1].getAttributeValue("AXValue"),
"Found correct text node"
);
is(
"this is some paragraph text",
text[2].getAttributeValue("AXValue"),
"Found correct text node for paragraph"
);
is(
"This is a list:",
text[3].getAttributeValue("AXValue"),
"Found correct text node for pre-list text node"
);
is(
"List item one",
text[4].getAttributeValue("AXValue"),
"Found correct text node for list item one"
);
is(
"List item two",
text[5].getAttributeValue("AXValue"),
"Found correct text node for list item two"
);
is(
"This is a link",
text[6].getAttributeValue("AXValue"),
"Found correct text node for link"
);
}
);
/**
* Test rotor with lists
*/
addAccessibleTask(
`
item one
item two
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXListSearchKey",
AXImmediateDescendants: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const listCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(2, listCount, "Found 2 lists");
const lists = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
const ordered = getNativeInterface(accDoc, "ordered");
const unordered = getNativeInterface(accDoc, "unordered");
is(
unordered.getAttributeValue("AXChildren")[0].getAttributeValue("AXTitle"),
lists[0].getAttributeValue("AXChildren")[0].getAttributeValue("AXTitle"),
"Found correct unordered list"
);
is(
ordered.getAttributeValue("AXChildren")[0].getAttributeValue("AXTitle"),
lists[1].getAttributeValue("AXChildren")[0].getAttributeValue("AXTitle"),
"Found correct ordered list"
);
}
);
/*
* Test rotor with images
*/
addAccessibleTask(
`
`,
(browser, accDoc) => {
let searchPred = {
AXSearchKey: "AXImageSearchKey",
AXImmediateDescendantsOnly: 0,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
let images = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(images.length, 3, "Found three images");
const img1 = getNativeInterface(accDoc, "img1");
const img2 = getNativeInterface(accDoc, "img2");
const img3 = getNativeInterface(accDoc, "img3");
is(
img1.getAttributeValue("AXDescription"),
images[0].getAttributeValue("AXDescription"),
"Found correct image"
);
is(
img2.getAttributeValue("AXDescription"),
images[1].getAttributeValue("AXDescription"),
"Found correct image"
);
is(
img3.getAttributeValue("AXDescription"),
images[2].getAttributeValue("AXDescription"),
"Found correct image"
);
}
);
/**
* Test rotor with frames
*/
addAccessibleTask(
`
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXFrameSearchKey",
AXImmediateDescendantsOnly: 0,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const frameCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(3, frameCount, "Found 3 frames");
}
);
/**
* Test rotor with static text
*/
addAccessibleTask(
`
Hello I am a heading
This is some regular text.this is some paragraph text
This is a list:
List item one
List item two
This is a link
`,
async (browser, accDoc) => {
const searchPred = {
AXSearchKey: "AXStaticTextSearchKey",
AXImmediateDescendants: 0,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const textCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(7, textCount, "Found 7 pieces of text");
const text = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
is(
"Hello I am a heading",
text[0].getAttributeValue("AXValue"),
"Found correct text node for heading"
);
is(
"This is some regular text.",
text[1].getAttributeValue("AXValue"),
"Found correct text node"
);
is(
"this is some paragraph text",
text[2].getAttributeValue("AXValue"),
"Found correct text node for paragraph"
);
is(
"This is a list:",
text[3].getAttributeValue("AXValue"),
"Found correct text node for pre-list text node"
);
is(
"List item one",
text[4].getAttributeValue("AXValue"),
"Found correct text node for list item one"
);
is(
"List item two",
text[5].getAttributeValue("AXValue"),
"Found correct text node for list item two"
);
is(
"This is a link",
text[6].getAttributeValue("AXValue"),
"Found correct text node for link"
);
}
);
/**
* Test search with non-webarea root
*/
addAccessibleTask(
`
`,
async (browser, accDoc) => {
let searchPred = {
AXSearchKey: "AXAnyTypeSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
};
const searchRoot = getNativeInterface(accDoc, "searchroot");
const resultCount = searchRoot.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(resultCount, 2, "Found 2 items");
const p1 = getNativeInterface(accDoc, "p1");
searchPred = {
AXSearchKey: "AXAnyTypeSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
AXStartElement: p1,
};
let results = searchRoot.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
Assert.deepEqual(
results.map(r => r.getAttributeValue("AXDOMIdentifier")),
["p2"],
"Result is next group sibling"
);
searchPred = {
AXSearchKey: "AXAnyTypeSearchKey",
AXImmediateDescendantsOnly: 1,
AXResultsLimit: -1,
AXDirection: "AXDirectionPrevious",
};
results = searchRoot.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
Assert.deepEqual(
results.map(r => r.getAttributeValue("AXDOMIdentifier")),
["p2", "p1"],
"A reverse search should return groups in reverse"
);
}
);
/**
* Test search text
*/
addAccessibleTask(
`
It's about the future, isn't it?
Okay, alright, Saturday is good, Saturday's good, I could spend a week in 1955.
I could hang out, you could show me around.
There's that word again, heavy.
`,
async (browser, f, accDoc) => {
let searchPred = {
AXSearchKey: "AXAnyTypeSearchKey",
AXResultsLimit: -1,
AXDirection: "AXDirectionNext",
AXSearchText: "could",
};
const webArea = accDoc.nativeInterface.QueryInterface(
Ci.nsIAccessibleMacInterface
);
is(
webArea.getAttributeValue("AXRole"),
"AXWebArea",
"Got web area accessible"
);
const textSearchCount = webArea.getParameterizedAttributeValue(
"AXUIElementCountForSearchPredicate",
NSDictionary(searchPred)
);
is(textSearchCount, 2, "Found 2 matching items in text search");
const results = webArea.getParameterizedAttributeValue(
"AXUIElementsForSearchPredicate",
NSDictionary(searchPred)
);
info(results.map(r => r.getAttributeValue("AXMozDebugDescription")));
Assert.deepEqual(
results.map(r => r.getAttributeValue("AXValue")),
[
"Okay, alright, Saturday is good, Saturday's good, I could spend a week in 1955.",
"I could hang out, you could show me around.",
],
"Correct text search results"
);
},
{ topLevel: false, iframe: true, remoteIframe: true }
);