@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.
- package/.claude/settings.local.json +8 -1
- package/README.md +21 -1
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/coverage-final.json +51 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +161 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/test-utils/docs/scripts/core.js.html +2263 -0
- package/coverage/test-utils/docs/scripts/core.min.js.html +151 -0
- package/coverage/test-utils/docs/scripts/index.html +176 -0
- package/coverage/test-utils/docs/scripts/resize.js.html +355 -0
- package/coverage/test-utils/docs/scripts/search.js.html +880 -0
- package/coverage/test-utils/docs/scripts/search.min.js.html +100 -0
- package/coverage/test-utils/docs/scripts/third-party/fuse.js.html +109 -0
- package/coverage/test-utils/docs/scripts/third-party/hljs-line-num-original.js.html +1192 -0
- package/coverage/test-utils/docs/scripts/third-party/hljs-line-num.js.html +85 -0
- package/coverage/test-utils/docs/scripts/third-party/hljs-original.js.html +15598 -0
- package/coverage/test-utils/docs/scripts/third-party/hljs.js.html +85 -0
- package/coverage/test-utils/docs/scripts/third-party/index.html +236 -0
- package/coverage/test-utils/docs/scripts/third-party/popper.js.html +100 -0
- package/coverage/test-utils/docs/scripts/third-party/tippy.js.html +88 -0
- package/coverage/test-utils/docs/scripts/third-party/tocbot.js.html +2098 -0
- package/coverage/test-utils/docs/scripts/third-party/tocbot.min.js.html +85 -0
- package/coverage/test-utils/index.html +131 -0
- package/coverage/test-utils/src/arrayUtils.js.html +283 -0
- package/coverage/test-utils/src/domUtils.js.html +622 -0
- package/coverage/test-utils/src/getAccessibleName.js.html +1444 -0
- package/coverage/test-utils/src/getAccessibleText.js.html +271 -0
- package/coverage/test-utils/src/getAriaAttributesByElement.js.html +142 -0
- package/coverage/test-utils/src/getCSSGeneratedContent.js.html +265 -0
- package/coverage/test-utils/src/getComputedRole.js.html +592 -0
- package/coverage/test-utils/src/getFocusableElements.js.html +163 -0
- package/coverage/test-utils/src/getGeneratedContent.js.html +130 -0
- package/coverage/test-utils/src/getImageText.js.html +160 -0
- package/coverage/test-utils/src/getStyleObject.js.html +220 -0
- package/coverage/test-utils/src/hasAccessibleName.js.html +166 -0
- package/coverage/test-utils/src/hasAttribute.js.html +130 -0
- package/coverage/test-utils/src/hasCSSGeneratedContent.js.html +145 -0
- package/coverage/test-utils/src/hasHiddenParent.js.html +172 -0
- package/coverage/test-utils/src/hasParent.js.html +247 -0
- package/coverage/test-utils/src/hasValidAriaAttributes.js.html +175 -0
- package/coverage/test-utils/src/hasValidAriaRole.js.html +172 -0
- package/coverage/test-utils/src/index.html +611 -0
- package/coverage/test-utils/src/index.js.html +274 -0
- package/coverage/test-utils/src/interactiveRoles.js.html +145 -0
- package/coverage/test-utils/src/isAriaAttributesValid.js.html +304 -0
- package/coverage/test-utils/src/isComplexTable.js.html +412 -0
- package/coverage/test-utils/src/isDataTable.js.html +799 -0
- package/coverage/test-utils/src/isFocusable.js.html +187 -0
- package/coverage/test-utils/src/isHidden.js.html +136 -0
- package/coverage/test-utils/src/isOffScreen.js.html +133 -0
- package/coverage/test-utils/src/isValidUrl.js.html +124 -0
- package/coverage/test-utils/src/isVisible.js.html +271 -0
- package/coverage/test-utils/src/listEventListeners.js.html +370 -0
- package/coverage/test-utils/src/queryCache.js.html +1156 -0
- package/coverage/test-utils/src/stringUtils.js.html +535 -0
- package/coverage/test-utils/src/testContrast.js.html +784 -0
- package/coverage/test-utils/src/testLang.js.html +1810 -0
- package/coverage/test-utils/src/testOrder.js.html +355 -0
- package/coverage/test-utils/vitest.config.browser.js.html +133 -0
- package/coverage/test-utils/vitest.config.js.html +157 -0
- package/package.json +12 -2
- package/src/arrayUtils.js +7 -12
- package/src/domUtils.js +1 -16
- package/src/getAccessibleName.js +3 -11
- package/src/getAccessibleText.js +3 -5
- package/src/getAriaAttributesByElement.js +1 -1
- package/src/getCSSGeneratedContent.js +7 -2
- package/src/getComputedRole.js +7 -2
- package/src/getFocusableElements.js +5 -1
- package/src/getGeneratedContent.js +5 -1
- package/src/getImageText.js +6 -2
- package/src/getStyleObject.js +5 -1
- package/src/hasAccessibleName.js +2 -10
- package/src/hasAttribute.js +5 -1
- package/src/hasCSSGeneratedContent.js +6 -2
- package/src/hasHiddenParent.js +2 -2
- package/src/hasParent.js +5 -1
- package/src/hasValidAriaAttributes.js +6 -2
- package/src/hasValidAriaRole.js +5 -1
- package/src/index.js +74 -31
- package/src/interactiveRoles.js +1 -1
- package/src/isAriaAttributesValid.js +6 -2
- package/src/isComplexTable.js +11 -4
- package/src/isDataTable.js +10 -5
- package/src/isFocusable.js +5 -1
- package/src/isHidden.js +1 -1
- package/src/isOffScreen.js +5 -1
- package/src/isValidUrl.js +5 -1
- package/src/isVisible.js +5 -1
- package/src/listEventListeners.js +95 -0
- package/src/queryCache.js +358 -0
- package/src/testContrast.js +5 -1
- package/src/testLang.js +19 -7
- package/src/testOrder.js +8 -3
- package/test/browser-setup.js +68 -0
- package/test/getCSSGeneratedContent.browser.test.js +125 -0
- package/test/hasCSSGeneratedContent.test.js +9 -7
- package/test/listEventListeners.test.js +310 -0
- package/test/queryCache.test.js +465 -0
- package/test/setup.js +3 -1
- package/test/testOrder.test.js +10 -115
- package/todo.md +1 -0
- package/vitest.config.browser.js +17 -0
- package/vitest.config.js +1 -0
package/src/index.js
CHANGED
|
@@ -5,60 +5,103 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// Array utilities
|
|
8
|
-
|
|
8
|
+
const arrayUtils = require('./arrayUtils.js');
|
|
9
9
|
|
|
10
10
|
// DOM utilities
|
|
11
|
-
|
|
11
|
+
const domUtils = require('./domUtils.js');
|
|
12
12
|
|
|
13
13
|
// Accessibility name computation
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
33
|
-
|
|
32
|
+
const isComplexTable = require('./isComplexTable.js');
|
|
33
|
+
const isDataTable = require('./isDataTable.js');
|
|
34
34
|
|
|
35
35
|
// Visibility and positioning
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
43
|
-
|
|
42
|
+
const hasParent = require('./hasParent.js');
|
|
43
|
+
const hasAttribute = require('./hasAttribute.js');
|
|
44
44
|
|
|
45
45
|
// Focus management
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
const getFocusableElements = require('./getFocusableElements.js');
|
|
47
|
+
const isFocusable = require('./isFocusable.js');
|
|
48
48
|
|
|
49
49
|
// Role computation
|
|
50
|
-
|
|
50
|
+
const getComputedRole = require('./getComputedRole.js');
|
|
51
51
|
|
|
52
52
|
// Image utilities
|
|
53
|
-
|
|
53
|
+
const getImageText = require('./getImageText.js');
|
|
54
54
|
|
|
55
55
|
// Testing utilities
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
61
|
+
const isValidUrl = require('./isValidUrl.js');
|
|
62
62
|
|
|
63
63
|
// String utilities
|
|
64
|
-
|
|
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
|
+
};
|
package/src/interactiveRoles.js
CHANGED
|
@@ -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
|
-
|
|
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
|
+
};
|
package/src/isComplexTable.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+
};
|
package/src/isDataTable.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Import using object destructuring for better compatibility with tests
|
|
2
|
-
|
|
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
|
-
|
|
236
|
+
// Export the main function and utility functions
|
|
237
|
+
module.exports = {
|
|
238
|
+
isDataTable,
|
|
239
|
+
rowCount,
|
|
240
|
+
cellCount,
|
|
241
|
+
countBordersPct,
|
|
242
|
+
colCount,
|
|
243
|
+
cellColorDiffs
|
|
244
|
+
};
|
package/src/isFocusable.js
CHANGED
|
@@ -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
|
-
|
|
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
package/src/isOffScreen.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 };
|