helpers.js (3894B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { 7 reducers, 8 } = require("resource://devtools/client/accessibility/reducers/index.js"); 9 const CheckClass = require("resource://devtools/client/accessibility/components/Check.js"); 10 const FluentReact = require("resource://devtools/client/shared/vendor/fluent-react.js"); 11 12 const { 13 createStore, 14 combineReducers, 15 } = require("resource://devtools/client/shared/vendor/redux.js"); 16 17 /** 18 * Prepare the store for use in testing. 19 */ 20 function setupStore({ preloadedState } = {}) { 21 const store = createStore(combineReducers(reducers), preloadedState); 22 return store; 23 } 24 25 /** 26 * Build a mock accessible object. 27 * 28 * @param {object} form 29 * Data similar to what accessible actor passes to accessible front. 30 */ 31 function mockAccessible(form) { 32 return { 33 on: jest.fn(), 34 off: jest.fn(), 35 isDestroyed: () => !form?.actorID, 36 audit: jest.fn().mockReturnValue(Promise.resolve()), 37 ...form, 38 }; 39 } 40 41 /** 42 * 43 * @param {DOMNode} 44 * DOMNode that corresponds to a menu item in a menu list 45 * @param {object} 46 * Expected properties: 47 * - role: optional ARIA role for the menu item 48 * - checked: optional checked state for the menu item 49 * - disabled: optional disabled state for the menu item 50 * - label: optional text label for the menu item 51 */ 52 function checkMenuItem(menuItem, expected) { 53 expect(menuItem.tagName).toBe("BUTTON"); 54 if (expected.role) { 55 expect(menuItem.getAttribute("role")).toBe(expected.role); 56 } else if (typeof expected.checked !== "undefined") { 57 expect(menuItem.getAttribute("role")).toBe("menuitemcheckbox"); 58 } else { 59 expect(menuItem.getAttribute("role")).toBe("menuitem"); 60 } 61 62 if (typeof expected.checked !== "undefined") { 63 expect(menuItem.hasAttribute("aria-checked")).toBe(expected.checked); 64 } 65 66 if (expected.checked) { 67 expect(menuItem.getAttribute("aria-checked")).toBe("true"); 68 } 69 70 if (expected.disabled) { 71 expect(menuItem.hasAttribute("disabled")).toBe(true); 72 } 73 74 if (expected.label) { 75 expect(menuItem.textContent).toBe(expected.label); 76 } 77 } 78 79 /** 80 * 81 * @param {ReactWrapper} 82 * React wrapper for the top level check component. 83 * @param {object} 84 * Expected audit properties: 85 * - score: audit score 86 * - issue: audit issue type 87 */ 88 function testCustomCheck(wrapper, props) { 89 expect(wrapper.html()).toMatchSnapshot(); 90 expect(wrapper.children().length).toBe(1); 91 const check = wrapper.childAt(0); 92 expect(wrapper.find(CheckClass)).toStrictEqual(check); 93 testCheck(check, props); 94 } 95 96 /** 97 * 98 * @param {ReactWrapper} 99 * React wrapper for the check component. 100 * @param {object} 101 * Expected audit properties: 102 * - score: audit score 103 * - issue: audit issue type 104 */ 105 function testCheck(wrapper, props) { 106 expect(wrapper.html()).toMatchSnapshot(); 107 const container = wrapper.childAt(0); 108 expect(container.hasClass("accessibility-check")).toBe(true); 109 expect(container.prop("role")).toBe("presentation"); 110 expect(container.prop("tabIndex")).toBe("-1"); 111 expect(wrapper.props()).toMatchObject(props); 112 113 const localized = wrapper.find(FluentReact.Localized); 114 expect(localized.length).toBe(3); 115 116 const heading = localized.at(0).childAt(0); 117 expect(heading.type()).toBe("h3"); 118 expect(heading.hasClass("accessibility-check-header")).toBe(true); 119 120 const icon = localized.at(1).childAt(0); 121 expect(icon.type()).toBe("img"); 122 expect(icon.prop("data-score")).toEqual(props.score); 123 124 const annotation = localized.at(2).childAt(0); 125 expect(annotation.type()).toBe("p"); 126 expect(annotation.hasClass("accessibility-check-annotation")).toBe(true); 127 } 128 129 module.exports = { 130 checkMenuItem, 131 mockAccessible, 132 setupStore, 133 testCheck, 134 testCustomCheck, 135 };