Source code
Revision control
Copy as Markdown
Other Tools
/* Any copyright is dedicated to the Public Domain.
"use strict";
const {
reducers,
} = require("resource://devtools/client/accessibility/reducers/index.js");
const CheckClass = require("resource://devtools/client/accessibility/components/Check.js");
const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js");
const {
createStore,
combineReducers,
} = require("resource://devtools/client/shared/vendor/redux.js");
/**
* Prepare the store for use in testing.
*/
function setupStore({ preloadedState } = {}) {
const store = createStore(combineReducers(reducers), preloadedState);
return store;
}
/**
* Build a mock accessible object.
* @param {Object} form
* Data similar to what accessible actor passes to accessible front.
*/
function mockAccessible(form) {
return {
on: jest.fn(),
off: jest.fn(),
isDestroyed: () => !form?.actorID,
audit: jest.fn().mockReturnValue(Promise.resolve()),
...form,
};
}
/**
*
* @param {DOMNode}
* DOMNode that corresponds to a menu item in a menu list
* @param {Object}
* Expected properties:
* - role: optional ARIA role for the menu item
* - checked: optional checked state for the menu item
* - disabled: optional disabled state for the menu item
* - label: optional text label for the menu item
*/
function checkMenuItem(menuItem, expected) {
expect(menuItem.tagName).toBe("BUTTON");
if (expected.role) {
expect(menuItem.getAttribute("role")).toBe(expected.role);
} else if (typeof expected.checked !== "undefined") {
expect(menuItem.getAttribute("role")).toBe("menuitemcheckbox");
} else {
expect(menuItem.getAttribute("role")).toBe("menuitem");
}
if (typeof expected.checked !== "undefined") {
expect(menuItem.hasAttribute("aria-checked")).toBe(expected.checked);
}
if (expected.checked) {
expect(menuItem.getAttribute("aria-checked")).toBe("true");
}
if (expected.disabled) {
expect(menuItem.hasAttribute("disabled")).toBe(true);
}
if (expected.label) {
expect(menuItem.textContent).toBe(expected.label);
}
}
/**
*
* @param {ReactWrapper}
* React wrapper for the top level check component.
* @param {Object}
* Expected audit properties:
* - score: audit score
* - issue: audit issue type
*/
function testCustomCheck(wrapper, props) {
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.children().length).toBe(1);
const check = wrapper.childAt(0);
expect(wrapper.find(CheckClass)).toStrictEqual(check);
testCheck(check, props);
}
/**
*
* @param {ReactWrapper}
* React wrapper for the check component.
* @param {Object}
* Expected audit properties:
* - score: audit score
* - issue: audit issue type
*/
function testCheck(wrapper, props) {
expect(wrapper.html()).toMatchSnapshot();
const container = wrapper.childAt(0);
expect(container.hasClass("accessibility-check")).toBe(true);
expect(container.prop("role")).toBe("presentation");
expect(container.prop("tabIndex")).toBe("-1");
expect(wrapper.props()).toMatchObject(props);
const localized = wrapper.find(FluentReact.Localized);
expect(localized.length).toBe(3);
const heading = localized.at(0).childAt(0);
expect(heading.type()).toBe("h3");
expect(heading.hasClass("accessibility-check-header")).toBe(true);
const icon = localized.at(1).childAt(0);
expect(icon.type()).toBe("img");
expect(icon.prop("data-score")).toEqual(props.score);
const annotation = localized.at(2).childAt(0);
expect(annotation.type()).toBe("p");
expect(annotation.hasClass("accessibility-check-annotation")).toBe(true);
}
module.exports = {
checkMenuItem,
mockAccessible,
setupStore,
testCheck,
testCustomCheck,
};