summaryrefslogtreecommitdiffstats
path: root/devtools/client/accessibility/test/node/helpers.js
blob: bfb14c258cbcc206ffcd5c2ba281f059a2092055 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"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,
};