@afixt/test-utils 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/.claude/settings.local.json +8 -1
  2. package/README.md +21 -1
  3. package/coverage/base.css +224 -0
  4. package/coverage/block-navigation.js +87 -0
  5. package/coverage/coverage-final.json +51 -0
  6. package/coverage/favicon.png +0 -0
  7. package/coverage/index.html +161 -0
  8. package/coverage/prettify.css +1 -0
  9. package/coverage/prettify.js +2 -0
  10. package/coverage/sort-arrow-sprite.png +0 -0
  11. package/coverage/sorter.js +196 -0
  12. package/coverage/test-utils/docs/scripts/core.js.html +2263 -0
  13. package/coverage/test-utils/docs/scripts/core.min.js.html +151 -0
  14. package/coverage/test-utils/docs/scripts/index.html +176 -0
  15. package/coverage/test-utils/docs/scripts/resize.js.html +355 -0
  16. package/coverage/test-utils/docs/scripts/search.js.html +880 -0
  17. package/coverage/test-utils/docs/scripts/search.min.js.html +100 -0
  18. package/coverage/test-utils/docs/scripts/third-party/fuse.js.html +109 -0
  19. package/coverage/test-utils/docs/scripts/third-party/hljs-line-num-original.js.html +1192 -0
  20. package/coverage/test-utils/docs/scripts/third-party/hljs-line-num.js.html +85 -0
  21. package/coverage/test-utils/docs/scripts/third-party/hljs-original.js.html +15598 -0
  22. package/coverage/test-utils/docs/scripts/third-party/hljs.js.html +85 -0
  23. package/coverage/test-utils/docs/scripts/third-party/index.html +236 -0
  24. package/coverage/test-utils/docs/scripts/third-party/popper.js.html +100 -0
  25. package/coverage/test-utils/docs/scripts/third-party/tippy.js.html +88 -0
  26. package/coverage/test-utils/docs/scripts/third-party/tocbot.js.html +2098 -0
  27. package/coverage/test-utils/docs/scripts/third-party/tocbot.min.js.html +85 -0
  28. package/coverage/test-utils/index.html +131 -0
  29. package/coverage/test-utils/src/arrayUtils.js.html +283 -0
  30. package/coverage/test-utils/src/domUtils.js.html +622 -0
  31. package/coverage/test-utils/src/getAccessibleName.js.html +1444 -0
  32. package/coverage/test-utils/src/getAccessibleText.js.html +271 -0
  33. package/coverage/test-utils/src/getAriaAttributesByElement.js.html +142 -0
  34. package/coverage/test-utils/src/getCSSGeneratedContent.js.html +265 -0
  35. package/coverage/test-utils/src/getComputedRole.js.html +592 -0
  36. package/coverage/test-utils/src/getFocusableElements.js.html +163 -0
  37. package/coverage/test-utils/src/getGeneratedContent.js.html +130 -0
  38. package/coverage/test-utils/src/getImageText.js.html +160 -0
  39. package/coverage/test-utils/src/getStyleObject.js.html +220 -0
  40. package/coverage/test-utils/src/hasAccessibleName.js.html +166 -0
  41. package/coverage/test-utils/src/hasAttribute.js.html +130 -0
  42. package/coverage/test-utils/src/hasCSSGeneratedContent.js.html +145 -0
  43. package/coverage/test-utils/src/hasHiddenParent.js.html +172 -0
  44. package/coverage/test-utils/src/hasParent.js.html +247 -0
  45. package/coverage/test-utils/src/hasValidAriaAttributes.js.html +175 -0
  46. package/coverage/test-utils/src/hasValidAriaRole.js.html +172 -0
  47. package/coverage/test-utils/src/index.html +611 -0
  48. package/coverage/test-utils/src/index.js.html +274 -0
  49. package/coverage/test-utils/src/interactiveRoles.js.html +145 -0
  50. package/coverage/test-utils/src/isAriaAttributesValid.js.html +304 -0
  51. package/coverage/test-utils/src/isComplexTable.js.html +412 -0
  52. package/coverage/test-utils/src/isDataTable.js.html +799 -0
  53. package/coverage/test-utils/src/isFocusable.js.html +187 -0
  54. package/coverage/test-utils/src/isHidden.js.html +136 -0
  55. package/coverage/test-utils/src/isOffScreen.js.html +133 -0
  56. package/coverage/test-utils/src/isValidUrl.js.html +124 -0
  57. package/coverage/test-utils/src/isVisible.js.html +271 -0
  58. package/coverage/test-utils/src/listEventListeners.js.html +370 -0
  59. package/coverage/test-utils/src/queryCache.js.html +1156 -0
  60. package/coverage/test-utils/src/stringUtils.js.html +535 -0
  61. package/coverage/test-utils/src/testContrast.js.html +784 -0
  62. package/coverage/test-utils/src/testLang.js.html +1810 -0
  63. package/coverage/test-utils/src/testOrder.js.html +355 -0
  64. package/coverage/test-utils/vitest.config.browser.js.html +133 -0
  65. package/coverage/test-utils/vitest.config.js.html +157 -0
  66. package/package.json +12 -2
  67. package/src/arrayUtils.js +7 -12
  68. package/src/domUtils.js +1 -16
  69. package/src/getAccessibleName.js +3 -11
  70. package/src/getAccessibleText.js +3 -5
  71. package/src/getAriaAttributesByElement.js +1 -1
  72. package/src/getCSSGeneratedContent.js +7 -2
  73. package/src/getComputedRole.js +7 -2
  74. package/src/getFocusableElements.js +5 -1
  75. package/src/getGeneratedContent.js +5 -1
  76. package/src/getImageText.js +6 -2
  77. package/src/getStyleObject.js +5 -1
  78. package/src/hasAccessibleName.js +2 -10
  79. package/src/hasAttribute.js +5 -1
  80. package/src/hasCSSGeneratedContent.js +6 -2
  81. package/src/hasHiddenParent.js +2 -2
  82. package/src/hasParent.js +5 -1
  83. package/src/hasValidAriaAttributes.js +6 -2
  84. package/src/hasValidAriaRole.js +5 -1
  85. package/src/index.js +74 -31
  86. package/src/interactiveRoles.js +1 -1
  87. package/src/isAriaAttributesValid.js +6 -2
  88. package/src/isComplexTable.js +11 -4
  89. package/src/isDataTable.js +10 -5
  90. package/src/isFocusable.js +5 -1
  91. package/src/isHidden.js +1 -1
  92. package/src/isOffScreen.js +5 -1
  93. package/src/isValidUrl.js +5 -1
  94. package/src/isVisible.js +5 -1
  95. package/src/listEventListeners.js +95 -0
  96. package/src/queryCache.js +358 -0
  97. package/src/testContrast.js +5 -1
  98. package/src/testLang.js +19 -7
  99. package/src/testOrder.js +8 -3
  100. package/test/browser-setup.js +68 -0
  101. package/test/getCSSGeneratedContent.browser.test.js +125 -0
  102. package/test/hasCSSGeneratedContent.test.js +9 -7
  103. package/test/listEventListeners.test.js +310 -0
  104. package/test/queryCache.test.js +465 -0
  105. package/test/setup.js +3 -1
  106. package/test/testOrder.test.js +10 -115
  107. package/todo.md +1 -0
  108. package/vitest.config.browser.js +17 -0
  109. package/vitest.config.js +1 -0
package/src/index.js CHANGED
@@ -5,60 +5,103 @@
5
5
  */
6
6
 
7
7
  // Array utilities
8
- export * from './arrayUtils.js';
8
+ const arrayUtils = require('./arrayUtils.js');
9
9
 
10
10
  // DOM utilities
11
- export * from './domUtils.js';
11
+ const domUtils = require('./domUtils.js');
12
12
 
13
13
  // Accessibility name computation
14
- export * from './getAccessibleName.js';
15
- export * from './getAccessibleText.js';
16
- export * from './hasAccessibleName.js';
14
+ const getAccessibleName = require('./getAccessibleName.js');
15
+ const getAccessibleText = require('./getAccessibleText.js');
16
+ const hasAccessibleName = require('./hasAccessibleName.js');
17
17
 
18
18
  // ARIA utilities
19
- export * from './getAriaAttributesByElement.js';
20
- export * from './hasValidAriaAttributes.js';
21
- export * from './hasValidAriaRole.js';
22
- export * from './isAriaAttributesValid.js';
23
- export * from './interactiveRoles.js';
19
+ const getAriaAttributesByElement = require('./getAriaAttributesByElement.js');
20
+ const hasValidAriaAttributes = require('./hasValidAriaAttributes.js');
21
+ const hasValidAriaRole = require('./hasValidAriaRole.js');
22
+ const isAriaAttributesValid = require('./isAriaAttributesValid.js');
23
+ const interactiveRoles = require('./interactiveRoles.js');
24
24
 
25
25
  // CSS utilities
26
- export * from './getCSSGeneratedContent.js';
27
- export * from './getGeneratedContent.js';
28
- export * from './getStyleObject.js';
29
- export * from './hasCSSGeneratedContent.js';
26
+ const getCSSGeneratedContent = require('./getCSSGeneratedContent.js');
27
+ const getGeneratedContent = require('./getGeneratedContent.js');
28
+ const getStyleObject = require('./getStyleObject.js');
29
+ const hasCSSGeneratedContent = require('./hasCSSGeneratedContent.js');
30
30
 
31
31
  // Table utilities
32
- export * from './isComplexTable.js';
33
- export * from './isDataTable.js';
32
+ const isComplexTable = require('./isComplexTable.js');
33
+ const isDataTable = require('./isDataTable.js');
34
34
 
35
35
  // Visibility and positioning
36
- export * from './isHidden.js';
37
- export * from './isOffScreen.js';
38
- export * from './isVisible.js';
39
- export * from './hasHiddenParent.js';
36
+ const isHidden = require('./isHidden.js');
37
+ const isOffScreen = require('./isOffScreen.js');
38
+ const isVisible = require('./isVisible.js');
39
+ const hasHiddenParent = require('./hasHiddenParent.js');
40
40
 
41
41
  // Element relationships
42
- export * from './hasParent.js';
43
- export * from './hasAttribute.js';
42
+ const hasParent = require('./hasParent.js');
43
+ const hasAttribute = require('./hasAttribute.js');
44
44
 
45
45
  // Focus management
46
- export * from './getFocusableElements.js';
47
- export * from './isFocusable.js';
46
+ const getFocusableElements = require('./getFocusableElements.js');
47
+ const isFocusable = require('./isFocusable.js');
48
48
 
49
49
  // Role computation
50
- export * from './getComputedRole.js';
50
+ const getComputedRole = require('./getComputedRole.js');
51
51
 
52
52
  // Image utilities
53
- export * from './getImageText.js';
53
+ const getImageText = require('./getImageText.js');
54
54
 
55
55
  // Testing utilities
56
- export * from './testContrast.js';
57
- export * from './testLang.js';
58
- export * from './testOrder.js';
56
+ const testContrast = require('./testContrast.js');
57
+ const testLang = require('./testLang.js');
58
+ const testOrder = require('./testOrder.js');
59
59
 
60
60
  // URL utilities
61
- export * from './isValidUrl.js';
61
+ const isValidUrl = require('./isValidUrl.js');
62
62
 
63
63
  // String utilities
64
- export * from './stringUtils.js';
64
+ const stringUtils = require('./stringUtils.js');
65
+
66
+ // Query cache utilities
67
+ const queryCache = require('./queryCache.js');
68
+
69
+ // List event listeners
70
+ const listEventListeners = require('./listEventListeners.js');
71
+
72
+ // Export all utilities
73
+ module.exports = {
74
+ ...arrayUtils,
75
+ ...domUtils,
76
+ ...getAccessibleName,
77
+ ...getAccessibleText,
78
+ ...hasAccessibleName,
79
+ ...getAriaAttributesByElement,
80
+ ...hasValidAriaAttributes,
81
+ ...hasValidAriaRole,
82
+ ...isAriaAttributesValid,
83
+ ...interactiveRoles,
84
+ ...getCSSGeneratedContent,
85
+ ...getGeneratedContent,
86
+ ...getStyleObject,
87
+ ...hasCSSGeneratedContent,
88
+ ...isComplexTable,
89
+ ...isDataTable,
90
+ ...isHidden,
91
+ ...isOffScreen,
92
+ ...isVisible,
93
+ ...hasHiddenParent,
94
+ ...hasParent,
95
+ ...hasAttribute,
96
+ ...getFocusableElements,
97
+ ...isFocusable,
98
+ ...getComputedRole,
99
+ ...getImageText,
100
+ ...testContrast,
101
+ ...testLang,
102
+ ...testOrder,
103
+ ...isValidUrl,
104
+ ...stringUtils,
105
+ ...queryCache,
106
+ ...listEventListeners
107
+ };
@@ -17,4 +17,4 @@ const interactiveRoles = [
17
17
  "tree",
18
18
  ];
19
19
 
20
- export default interactiveRoles;
20
+ module.exports = interactiveRoles;
@@ -65,10 +65,14 @@ const validAriaAttributes = new Set([
65
65
  * @param {string} attributeName - The name of the ARIA attribute to check (e.g., 'aria-label')
66
66
  * @returns {boolean} True if the attribute is a valid ARIA attribute, false otherwise
67
67
  */
68
- export function isAriaAttributeValid(attributeName) {
68
+ function isAriaAttributeValid(attributeName) {
69
69
  if (!attributeName || typeof attributeName !== 'string') {
70
70
  return false;
71
71
  }
72
72
 
73
73
  return validAriaAttributes.has(attributeName.toLowerCase());
74
- }
74
+ }
75
+
76
+ module.exports = {
77
+ isAriaAttributeValid
78
+ };
@@ -5,7 +5,7 @@
5
5
  * @param {HTMLElement} el - The table element to check.
6
6
  * @returns {boolean} True if the table has more than one row in the header, otherwise false.
7
7
  */
8
- export function checkMultiRowsInHeader(el) {
8
+ function checkMultiRowsInHeader(el) {
9
9
  return el.querySelectorAll("thead tr").length > 1;
10
10
  }
11
11
 
@@ -17,7 +17,7 @@ export function checkMultiRowsInHeader(el) {
17
17
  * @returns {boolean} - Returns true if there are more than one row
18
18
  * with at least one cell having a colspan attribute, otherwise false.
19
19
  */
20
- export function checkMultiRowsWithColspan(el) {
20
+ function checkMultiRowsWithColspan(el) {
21
21
  let rowsWithColspanCount = 0;
22
22
  el.querySelectorAll("tr").forEach((row) => {
23
23
  if (row.querySelectorAll("td[colspan]").length >= 1) {
@@ -37,7 +37,7 @@ export function checkMultiRowsWithColspan(el) {
37
37
  * @returns {boolean} - Returns `true` if the table has inconsistent
38
38
  * row or column spans, otherwise `false`.
39
39
  */
40
- export function checkInconsistent(el) {
40
+ function checkInconsistent(el) {
41
41
  let result = false;
42
42
  let clone = el.cloneNode(true);
43
43
 
@@ -94,7 +94,7 @@ export function checkInconsistent(el) {
94
94
  * @param {HTMLElement} el - The table element to check.
95
95
  * @returns {boolean} - Returns true if the table is complex, otherwise false.
96
96
  */
97
- export function isComplexTable(el) {
97
+ function isComplexTable(el) {
98
98
  if (!el) return true;
99
99
  let clone = el.cloneNode(true);
100
100
 
@@ -107,3 +107,10 @@ export function isComplexTable(el) {
107
107
 
108
108
  return multiRowsInHeader || inconsistent || multiRowsWithColspan;
109
109
  }
110
+
111
+ module.exports = {
112
+ checkMultiRowsInHeader,
113
+ checkMultiRowsWithColspan,
114
+ checkInconsistent,
115
+ isComplexTable
116
+ };
@@ -1,5 +1,5 @@
1
1
  // Import using object destructuring for better compatibility with tests
2
- import { arrayCount } from './arrayUtils.js';
2
+ const { arrayCount } = require('./arrayUtils.js');
3
3
 
4
4
  /**
5
5
  * Returns the number of rows in the given table element.
@@ -98,8 +98,6 @@ function cellColorDiffs(table, maxColors, maxDiffs) {
98
98
  return false;
99
99
  }
100
100
 
101
- // Export the utility functions
102
- export { rowCount, cellCount, countBordersPct, colCount, cellColorDiffs };
103
101
 
104
102
  /**
105
103
  * Determines if a given table element is a data table based on various heuristics and options.
@@ -235,5 +233,12 @@ function isDataTable(table, options = {}) {
235
233
  return true;
236
234
  }
237
235
 
238
- // Export the main function
239
- export { isDataTable };
236
+ // Export the main function and utility functions
237
+ module.exports = {
238
+ isDataTable,
239
+ rowCount,
240
+ cellCount,
241
+ countBordersPct,
242
+ colCount,
243
+ cellColorDiffs
244
+ };
@@ -3,7 +3,7 @@
3
3
  * @param {Element} element - The HTML element to check.
4
4
  * @returns {boolean} - Returns true if the element is focusable, otherwise false.
5
5
  */
6
- export function isFocusable(element) {
6
+ function isFocusable(element) {
7
7
  if (!element) return false;
8
8
 
9
9
  const nodeName = element.nodeName.toLowerCase();
@@ -32,3 +32,7 @@ export function isFocusable(element) {
32
32
  // This is some other page element that is not normally focusable
33
33
  return false;
34
34
  }
35
+
36
+ module.exports = {
37
+ isFocusable
38
+ };
package/src/isHidden.js CHANGED
@@ -14,4 +14,4 @@ const isHidden = (element) => {
14
14
  );
15
15
  };
16
16
 
17
- export default isHidden;
17
+ module.exports = isHidden;
@@ -3,7 +3,7 @@
3
3
  * @param {Element} element - The element to check.
4
4
  * @returns {boolean} - True if the element is off-screen, otherwise false.
5
5
  */
6
- export function isOffScreen(element) {
6
+ function isOffScreen(element) {
7
7
  if (!element) return false;
8
8
 
9
9
  const rect = element.getBoundingClientRect();
@@ -14,3 +14,7 @@ export function isOffScreen(element) {
14
14
  rect.top > window.innerHeight
15
15
  );
16
16
  }
17
+
18
+ module.exports = {
19
+ isOffScreen
20
+ };
package/src/isValidUrl.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * @param {string} str - The string to validate.
4
4
  * @returns {boolean} - Returns true if the string is a valid URL, otherwise false.
5
5
  */
6
- export function isValidUrl(str) {
6
+ function isValidUrl(str) {
7
7
  try {
8
8
  new URL(str);
9
9
  return true;
@@ -11,3 +11,7 @@ export function isValidUrl(str) {
11
11
  return false;
12
12
  }
13
13
  }
14
+
15
+ module.exports = {
16
+ isValidUrl
17
+ };
package/src/isVisible.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * @param {boolean} strict - Option to be more strict about visibility of aria-hidden="true" in addition to CSS display: none.
5
5
  * @returns {boolean}
6
6
  */
7
- export function isVisible(element, strict = false) {
7
+ function isVisible(element, strict = false) {
8
8
  if (!element) return false;
9
9
 
10
10
  const id = element.id;
@@ -60,3 +60,7 @@ export function isVisible(element, strict = false) {
60
60
 
61
61
  return visible;
62
62
  }
63
+
64
+ module.exports = {
65
+ isVisible
66
+ };
@@ -0,0 +1,95 @@
1
+ 'use strict';
2
+
3
+ const eventListenersMap = new WeakMap();
4
+
5
+ const originalAddEventListener = EventTarget.prototype.addEventListener;
6
+ const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
7
+
8
+ // Override addEventListener to track event listeners
9
+ EventTarget.prototype.addEventListener = function (type, listener, options) {
10
+ if (!eventListenersMap.has(this)) {
11
+ eventListenersMap.set(this, {});
12
+ }
13
+ const listeners = eventListenersMap.get(this);
14
+
15
+ if (!listeners[type]) {
16
+ listeners[type] = [];
17
+ }
18
+ listeners[type].push({ listener, options });
19
+
20
+ return originalAddEventListener.call(this, type, listener, options);
21
+ };
22
+
23
+ // Override removeEventListener to remove from tracking
24
+ EventTarget.prototype.removeEventListener = function (type, listener, options) {
25
+ if (eventListenersMap.has(this)) {
26
+ const listeners = eventListenersMap.get(this);
27
+ if (listeners[type]) {
28
+ listeners[type] = listeners[type].filter((l) => l.listener !== listener);
29
+ }
30
+ }
31
+ return originalRemoveEventListener.call(this, type, listener, options);
32
+ };
33
+
34
+ // Function to get XPath of an element
35
+ const getXPath = (element) => {
36
+ if (element.id) {
37
+ return `//*[@id="${element.id}"]`;
38
+ }
39
+ let path = '';
40
+ while (element && element.nodeType === Node.ELEMENT_NODE) {
41
+ let index = 0;
42
+ let sibling = element;
43
+ while (sibling) {
44
+ if (sibling.nodeName === element.nodeName) {
45
+ index++;
46
+ }
47
+ sibling = sibling.previousElementSibling;
48
+ }
49
+ path = `/${element.nodeName.toLowerCase()}[${index}]` + path;
50
+ element = element.parentNode;
51
+ }
52
+ return path;
53
+ };
54
+
55
+ // Function to get all event listeners on an element
56
+ const getEventListeners = (element) => {
57
+ return eventListenersMap.get(element) || {};
58
+ };
59
+
60
+ /**
61
+ * List all event listeners for an element and its children
62
+ * @param {Element} rootElement - The root element to start listing from (defaults to document)
63
+ * @returns {Array} Array of event listener objects with element, xpath, and event properties
64
+ */
65
+ const listEventListeners = (rootElement = document) => {
66
+ const eventListeners = [];
67
+
68
+ /**
69
+ * Process an element to extract its event listeners
70
+ * @param {Element} el - The element to process
71
+ */
72
+ function processElement(el) {
73
+ const listeners = getEventListeners(el);
74
+ if (Object.keys(listeners).length > 0) {
75
+ Object.keys(listeners).forEach((eventName) => {
76
+ eventListeners.push({
77
+ element: el.tagName.toLowerCase(),
78
+ xpath: getXPath(el),
79
+ event: eventName
80
+ });
81
+ });
82
+ }
83
+ }
84
+
85
+ // Process root element
86
+ processElement(rootElement);
87
+
88
+ // Process child elements
89
+ rootElement.querySelectorAll('*').forEach(processElement);
90
+
91
+ return eventListeners;
92
+ };
93
+
94
+ // Export functions
95
+ module.exports = { listEventListeners, getEventListeners };