@afixt/test-utils 1.0.2 → 1.1.1

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 (105) hide show
  1. package/.claude/settings.local.json +7 -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 +6 -1
  67. package/repairs-needed.md +84 -0
  68. package/src/arrayUtils.js +7 -12
  69. package/src/domUtils.js +1 -16
  70. package/src/getAccessibleName.js +10 -12
  71. package/src/getAccessibleText.js +10 -6
  72. package/src/getAriaAttributesByElement.js +1 -1
  73. package/src/getCSSGeneratedContent.js +6 -2
  74. package/src/getComputedRole.js +7 -2
  75. package/src/getFocusableElements.js +5 -1
  76. package/src/getGeneratedContent.js +5 -1
  77. package/src/getImageText.js +6 -2
  78. package/src/getStyleObject.js +5 -1
  79. package/src/hasAccessibleName.js +2 -10
  80. package/src/hasAttribute.js +5 -1
  81. package/src/hasCSSGeneratedContent.js +6 -2
  82. package/src/hasHiddenParent.js +2 -2
  83. package/src/hasParent.js +5 -1
  84. package/src/hasValidAriaAttributes.js +6 -2
  85. package/src/hasValidAriaRole.js +5 -1
  86. package/src/index.js +74 -31
  87. package/src/interactiveRoles.js +1 -1
  88. package/src/isAriaAttributesValid.js +6 -2
  89. package/src/isComplexTable.js +11 -4
  90. package/src/isDataTable.js +10 -5
  91. package/src/isFocusable.js +5 -1
  92. package/src/isHidden.js +1 -1
  93. package/src/isOffScreen.js +5 -1
  94. package/src/isValidUrl.js +5 -1
  95. package/src/isVisible.js +14 -2
  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/hasCSSGeneratedContent.test.js +9 -7
  101. package/test/queryCache.test.js +465 -0
  102. package/test/setup.js +3 -1
  103. package/test/testOrder.test.js +10 -115
  104. package/todo.md +2 -0
  105. package/vitest.config.js +1 -0
@@ -0,0 +1,157 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for test-utils/vitest.config.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../prettify.css" />
9
+ <link rel="stylesheet" href="../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../index.html">All files</a> / <a href="index.html">test-utils</a> vitest.config.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">0% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>0/24</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/1</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/1</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">0% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>0/24</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line low'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
91
+ <span class="cline-any cline-neutral">&nbsp;</span>
92
+ <span class="cline-any cline-no">&nbsp;</span>
93
+ <span class="cline-any cline-no">&nbsp;</span>
94
+ <span class="cline-any cline-no">&nbsp;</span>
95
+ <span class="cline-any cline-no">&nbsp;</span>
96
+ <span class="cline-any cline-no">&nbsp;</span>
97
+ <span class="cline-any cline-no">&nbsp;</span>
98
+ <span class="cline-any cline-no">&nbsp;</span>
99
+ <span class="cline-any cline-no">&nbsp;</span>
100
+ <span class="cline-any cline-no">&nbsp;</span>
101
+ <span class="cline-any cline-no">&nbsp;</span>
102
+ <span class="cline-any cline-no">&nbsp;</span>
103
+ <span class="cline-any cline-no">&nbsp;</span>
104
+ <span class="cline-any cline-no">&nbsp;</span>
105
+ <span class="cline-any cline-no">&nbsp;</span>
106
+ <span class="cline-any cline-no">&nbsp;</span>
107
+ <span class="cline-any cline-no">&nbsp;</span>
108
+ <span class="cline-any cline-no">&nbsp;</span>
109
+ <span class="cline-any cline-no">&nbsp;</span>
110
+ <span class="cline-any cline-no">&nbsp;</span>
111
+ <span class="cline-any cline-no">&nbsp;</span>
112
+ <span class="cline-any cline-no">&nbsp;</span>
113
+ <span class="cline-any cline-no">&nbsp;</span>
114
+ <span class="cline-any cline-no">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js"><span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" ><span class="branch-0 cbranch-no" title="branch not covered" >import { defineConfig } from 'vitest/config';</span></span></span>
115
+ &nbsp;
116
+ <span class="cstat-no" title="statement not covered" >export default defineConfig({</span>
117
+ <span class="cstat-no" title="statement not covered" > test: {</span>
118
+ <span class="cstat-no" title="statement not covered" > globals: true,</span>
119
+ <span class="cstat-no" title="statement not covered" > environment: 'jsdom',</span>
120
+ <span class="cstat-no" title="statement not covered" > setupFiles: './test/setup.js',</span>
121
+ <span class="cstat-no" title="statement not covered" > include: ['test/**/*.test.js'],</span>
122
+ <span class="cstat-no" title="statement not covered" > exclude: ['test/_template.test.js'],</span>
123
+ <span class="cstat-no" title="statement not covered" > deps: {</span>
124
+ <span class="cstat-no" title="statement not covered" > inline: [/^(?!.*vitest).*$/],</span>
125
+ <span class="cstat-no" title="statement not covered" > },</span>
126
+ <span class="cstat-no" title="statement not covered" > environmentOptions: {</span>
127
+ <span class="cstat-no" title="statement not covered" > jsdom: {</span>
128
+ <span class="cstat-no" title="statement not covered" > resources: 'usable',</span>
129
+ <span class="cstat-no" title="statement not covered" > },</span>
130
+ <span class="cstat-no" title="statement not covered" > },</span>
131
+ <span class="cstat-no" title="statement not covered" > coverage: {</span>
132
+ <span class="cstat-no" title="statement not covered" > provider: 'v8',</span>
133
+ <span class="cstat-no" title="statement not covered" > reporter: ['text', 'json', 'html'],</span>
134
+ <span class="cstat-no" title="statement not covered" > exclude: ['**/node_modules/**', 'test/**'],</span>
135
+ <span class="cstat-no" title="statement not covered" > reportsDirectory: './coverage',</span>
136
+ <span class="cstat-no" title="statement not covered" > },</span>
137
+ <span class="cstat-no" title="statement not covered" > },</span>
138
+ <span class="cstat-no" title="statement not covered" >});</span></pre></td></tr></table></pre>
139
+
140
+ <div class='push'></div><!-- for sticky footer -->
141
+ </div><!-- /wrapper -->
142
+ <div class='footer quiet pad2 space-top1 center small'>
143
+ Code coverage generated by
144
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
145
+ at 2025-06-23T19:41:12.391Z
146
+ </div>
147
+ <script src="../prettify.js"></script>
148
+ <script>
149
+ window.onload = function () {
150
+ prettyPrint();
151
+ };
152
+ </script>
153
+ <script src="../sorter.js"></script>
154
+ <script src="../block-navigation.js"></script>
155
+ </body>
156
+ </html>
157
+
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@afixt/test-utils",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "description": "Various utilities for accessibility testing",
5
+ "main": "src/index.js",
5
6
  "scripts": {
6
7
  "test": "vitest run",
7
8
  "test:watch": "vitest",
@@ -18,6 +19,10 @@
18
19
  "type": "git",
19
20
  "url": "git@github.com:AFixt/test-utils.git"
20
21
  },
22
+ "bugs": {
23
+ "url": "https://github.com/AFixt/test-utils/issues"
24
+ },
25
+ "homepage": "https://github.com/AFixt/test-utils",
21
26
  "author": "Karl Groves <karl.groves@afixt.com>",
22
27
  "license": "UNLICENSED",
23
28
  "engines": {
@@ -0,0 +1,84 @@
1
+ # Required Changes for @afixt/test-utils Library
2
+
3
+ ## Issue
4
+
5
+ The browser extension is throwing "Invalid input: element must be a DOM Element,
6
+ got: null" errors when viewing dynamic sites like CNN.com. The error originates
7
+ from the @afixt/test-utils library functions.
8
+
9
+ ## Root Cause
10
+
11
+ The `isVisible()` function (and potentially other functions) in
12
+ @afixt/test-utils throws an error when passed null or non-Element arguments.
13
+ This happens frequently during DOM mutations when:
14
+
15
+ 1. Elements are removed from the DOM during repair operations
16
+ 2. Mutation observers fire on disconnected elements
17
+ 3. Elements become stale between detection and processing
18
+
19
+ ## Required Changes
20
+
21
+ ### 1. isVisible() Function
22
+
23
+ The function needs to handle null/invalid inputs gracefully:
24
+
25
+ ```javascript
26
+ function isVisible(element, strict = false) {
27
+ // Add null check at the beginning
28
+ if (!element || !(element instanceof Element)) {
29
+ return false;
30
+ }
31
+
32
+ // Check if element is still connected to the DOM
33
+ if (!element.isConnected) {
34
+ return false;
35
+ }
36
+
37
+ // ... rest of the existing function
38
+ }
39
+ ```
40
+
41
+ ### 2. getAccessibleText() Function
42
+
43
+ Should handle null elements:
44
+
45
+ ```javascript
46
+ function getAccessibleText(element) {
47
+ if (!element || !(element instanceof Element)) {
48
+ return '';
49
+ }
50
+
51
+ if (!element.isConnected) {
52
+ return '';
53
+ }
54
+
55
+ // ... rest of the existing function
56
+ }
57
+ ```
58
+
59
+ ### 3. getAccessibleName() Function
60
+
61
+ Should handle null elements:
62
+
63
+ ```javascript
64
+ function getAccessibleName(element) {
65
+ if (!element || !(element instanceof Element)) {
66
+ return '';
67
+ }
68
+
69
+ if (!element.isConnected) {
70
+ return '';
71
+ }
72
+
73
+ // ... rest of the existing function
74
+ }
75
+ ```
76
+
77
+ ## Why These Changes Are Needed
78
+
79
+ 1. **Defensive Programming**: DOM elements can become null or disconnected at
80
+ any time, especially in dynamic web applications
81
+ 2. **Mutation Observer Behavior**: When observing DOM changes, elements can be
82
+ removed between the time a mutation is detected and when it's processed
83
+ 3. **Library Robustness**: A utility library should handle invalid inputs
84
+ gracefully rather than throwing errors
package/src/arrayUtils.js CHANGED
@@ -52,16 +52,11 @@ const arrayUtils = {
52
52
  cleanBlank
53
53
  };
54
54
 
55
- // Export for ES modules
56
- export { arrayUnique, arrayRemoveByValue, arrayCount, cleanBlank, arrayUtils };
57
-
58
55
  // Export for CommonJS
59
- if (typeof module !== 'undefined' && module.exports) {
60
- module.exports = {
61
- arrayUnique,
62
- arrayRemoveByValue,
63
- arrayCount,
64
- cleanBlank,
65
- arrayUtils
66
- };
67
- }
56
+ module.exports = {
57
+ arrayUnique,
58
+ arrayRemoveByValue,
59
+ arrayCount,
60
+ cleanBlank,
61
+ arrayUtils
62
+ };
package/src/domUtils.js CHANGED
@@ -57,7 +57,7 @@ const domUtils = {
57
57
  * @returns {string|boolean} A JSON string representing the attributes of the element, or false if no attributes are found.
58
58
  */
59
59
  getAttributesAsString(element) {
60
- const attrs = getAttributes(element);
60
+ const attrs = domUtils.getAttributes(element);
61
61
  return attrs ? JSON.stringify(attrs) : false;
62
62
  },
63
63
 
@@ -161,19 +161,4 @@ const domUtils = {
161
161
  },
162
162
  };
163
163
 
164
- module.exports = {
165
- hasAttr: domUtils.hasAttr,
166
- attrBegins: domUtils.attrBegins,
167
- containsNoCase: domUtils.containsNoCase,
168
- getAttributes: domUtils.getAttributes,
169
- getAttributesAsString: domUtils.getAttributesAsString,
170
- getConstructor: domUtils.getConstructor,
171
- getDocumentSize: domUtils.getDocumentSize,
172
- getElementsWithDuplicateIds: domUtils.getElementsWithDuplicateIds,
173
- getOuterHTML: domUtils.getOuterHTML,
174
- getXPath: domUtils.getXPath,
175
- hasFocus: domUtils.hasFocus,
176
- isFullyVisible: domUtils.isFullyVisible,
177
- };
178
-
179
164
  module.exports = domUtils;
@@ -1,5 +1,5 @@
1
- import { isEmpty } from "./stringUtils.js";
2
- import { getAccessibleText } from "./getAccessibleText.js";
1
+ const { isEmpty } = require("./stringUtils.js");
2
+ const { getAccessibleText } = require("./getAccessibleText.js");
3
3
 
4
4
  /**
5
5
  * Gets the accessible name of an element according to the accessible name calculation algorithm
@@ -7,7 +7,13 @@ import { getAccessibleText } from "./getAccessibleText.js";
7
7
  * @returns {string|boolean} The accessible name or false if none exists
8
8
  */
9
9
  function getAccessibleName(element) {
10
- if (!element) return false;
10
+ if (!element || !(element instanceof Element)) {
11
+ return false;
12
+ }
13
+
14
+ if (!element.isConnected) {
15
+ return false;
16
+ }
11
17
 
12
18
  // These are elements which are totally not able to be labeled at all.
13
19
  // Even if the title attribute is valid per HTML for these elements,
@@ -442,13 +448,5 @@ function strlen(str) {
442
448
  return typeof str === "string" && !isEmpty(str.trim()) ? str.trim().length : 0;
443
449
  }
444
450
 
445
- // Export as default for ES modules
446
- export default getAccessibleName;
447
-
448
451
  // Export the function for CommonJS module usage
449
- if (typeof module !== 'undefined' && module.exports) {
450
- module.exports = getAccessibleName;
451
- } else if (typeof window !== 'undefined') {
452
- // Add to window object for browser usage
453
- window.getAccessibleName = getAccessibleName;
454
- }
452
+ module.exports = getAccessibleName;
@@ -1,12 +1,18 @@
1
- import { isEmpty } from "./stringUtils.js";
1
+ const { isEmpty } = require("./stringUtils.js");
2
2
 
3
3
  /**
4
4
  * Get all accessible text for an element, including aria-labels and content from children.
5
5
  * @param {Element} el - The DOM element.
6
6
  * @returns {string} The accessible text.
7
7
  */
8
- export function getAccessibleText(el) {
9
- if (!el) return "";
8
+ function getAccessibleText(el) {
9
+ if (!el || !(el instanceof Element)) {
10
+ return '';
11
+ }
12
+
13
+ if (!el.isConnected) {
14
+ return '';
15
+ }
10
16
 
11
17
  let textContent = "";
12
18
 
@@ -58,6 +64,4 @@ export function getAccessibleText(el) {
58
64
  }
59
65
 
60
66
  // Export for CommonJS module usage
61
- if (typeof module !== 'undefined' && module.exports) {
62
- module.exports = { getAccessibleText };
63
- }
67
+ module.exports = { getAccessibleText };
@@ -16,4 +16,4 @@ const getAriaAttributes = (element) => {
16
16
  return result;
17
17
  };
18
18
 
19
- export default getAriaAttributes;
19
+ module.exports = getAriaAttributes;
@@ -7,7 +7,7 @@
7
7
  * @param {string} [pseudoElement='both'] - Which pseudo-element to check ('before', 'after', or 'both')
8
8
  * @returns {string|boolean} The generated content as a string or false if none exists
9
9
  */
10
- export function getCSSGeneratedContent(el, pseudoElement = 'both') {
10
+ function getCSSGeneratedContent(el, pseudoElement = 'both') {
11
11
  if (!el) return false;
12
12
 
13
13
  // jsdom doesn't fully support getComputedStyle for pseudo-elements
@@ -58,4 +58,8 @@ export function getCSSGeneratedContent(el, pseudoElement = 'both') {
58
58
  } catch (error) {
59
59
  return false;
60
60
  }
61
- }
61
+ }
62
+
63
+ module.exports = {
64
+ getCSSGeneratedContent
65
+ };
@@ -1,4 +1,4 @@
1
- export const roleMapping = {
1
+ const roleMapping = {
2
2
  'a': {
3
3
  '[href]': 'link',
4
4
  ':not([href])': 'text'
@@ -146,7 +146,7 @@ export const roleMapping = {
146
146
  * @param {HTMLElement} element - The HTML element to get the role for.
147
147
  * @returns {string|undefined} The computed role of the element, or undefined if no role is found.
148
148
  */
149
- export function getComputedRole(element) {
149
+ function getComputedRole(element) {
150
150
  if (!element) return undefined;
151
151
 
152
152
  const roleAttr = element.getAttribute('role');
@@ -167,3 +167,8 @@ export function getComputedRole(element) {
167
167
 
168
168
  return undefined;
169
169
  }
170
+
171
+ module.exports = {
172
+ roleMapping,
173
+ getComputedRole
174
+ };
@@ -3,7 +3,7 @@
3
3
  * @param {Element} el - the element to be tested
4
4
  * @returns {Array} - Array of focusable elements
5
5
  */
6
- export function getFocusableElements(el) {
6
+ function getFocusableElements(el) {
7
7
  const focusableSelectors = [
8
8
  "a[href]",
9
9
  "area",
@@ -24,3 +24,7 @@ export function getFocusableElements(el) {
24
24
  );
25
25
  });
26
26
  }
27
+
28
+ module.exports = {
29
+ getFocusableElements
30
+ };
@@ -3,7 +3,7 @@
3
3
  * @param {Element} el - The DOM element.
4
4
  * @returns {string|boolean} The generated content or `false` if not available.
5
5
  */
6
- export function getGeneratedContent(el) {
6
+ function getGeneratedContent(el) {
7
7
  if (!el) return false;
8
8
  const computedStyle = getComputedStyle(el);
9
9
  const before = computedStyle.getPropertyValue("content", "::before") || "";
@@ -13,3 +13,7 @@ export function getGeneratedContent(el) {
13
13
  ? `${before} ${inner} ${after}`.trim()
14
14
  : false;
15
15
  }
16
+
17
+ module.exports = {
18
+ getGeneratedContent
19
+ };
@@ -1,11 +1,11 @@
1
- import Tesseract from 'tesseract.js';
1
+ const Tesseract = require('tesseract.js');
2
2
 
3
3
  /**
4
4
  * Extracts text from an image using OCR.
5
5
  * @param {string} imagePath - The path or URL of the image.
6
6
  * @returns {Promise<string|false>} Extracted text if found, otherwise false.
7
7
  */
8
- export async function getImageText(imagePath) {
8
+ async function getImageText(imagePath) {
9
9
  try {
10
10
  const { data: { text } } = await Tesseract.recognize(
11
11
  imagePath,
@@ -23,3 +23,7 @@ export async function getImageText(imagePath) {
23
23
 
24
24
  // Example usage:
25
25
  // getImageText('path/to/image.jpg').then(result => console.log(result));
26
+
27
+ module.exports = {
28
+ getImageText
29
+ };
@@ -7,7 +7,7 @@
7
7
  * with property names in camelCase. Returns false if the style object
8
8
  * cannot be retrieved.
9
9
  */
10
- export function getStyleObject(el) {
10
+ function getStyleObject(el) {
11
11
  // Ensure we have a valid DOM element
12
12
  if (!el || !(el instanceof Element)) {
13
13
  return false;
@@ -43,3 +43,7 @@ export function getStyleObject(el) {
43
43
  return false;
44
44
  }
45
45
  }
46
+
47
+ module.exports = {
48
+ getStyleObject
49
+ };
@@ -1,4 +1,4 @@
1
- import getAccessibleName from "./getAccessibleName.js";
1
+ const getAccessibleName = require("./getAccessibleName.js");
2
2
 
3
3
  /**
4
4
  * Determines if an element has an accessible name
@@ -16,13 +16,5 @@ function hasAccessibleName(element) {
16
16
  return accessibleName !== false;
17
17
  }
18
18
 
19
- // Export for ES modules
20
- export default hasAccessibleName;
21
-
22
19
  // Export for CommonJS
23
- if (typeof module !== 'undefined' && module.exports) {
24
- module.exports = hasAccessibleName;
25
- } else if (typeof window !== 'undefined') {
26
- // Add to window object for browser usage
27
- window.hasAccessibleName = hasAccessibleName;
28
- }
20
+ module.exports = hasAccessibleName;
@@ -6,10 +6,14 @@
6
6
  * @param {Element} element - The DOM element to check the attribute on.
7
7
  * @returns {boolean} - Returns true if the attribute exists on the element, otherwise false.
8
8
  */
9
- export function hasAttribute(attribute, element) {
9
+ function hasAttribute(attribute, element) {
10
10
  if (!element || !(element instanceof Element) || typeof attribute !== 'string') {
11
11
  return false;
12
12
  }
13
13
 
14
14
  return element.hasAttribute(attribute);
15
+ }
16
+
17
+ module.exports = {
18
+ hasAttribute
15
19
  };
@@ -1,5 +1,5 @@
1
1
 
2
- import { getGeneratedContent } from './getGeneratedContent.js';
2
+ const { getGeneratedContent } = require('./getGeneratedContent.js');
3
3
 
4
4
  /**
5
5
  * Checks if an element has CSS generated content in its ::before or ::after pseudo-elements
@@ -8,7 +8,7 @@ import { getGeneratedContent } from './getGeneratedContent.js';
8
8
  * @param {HTMLElement} el - The element to check for generated content.
9
9
  * @returns {boolean} True if the element has any generated content, otherwise false.
10
10
  */
11
- export function hasCSSGeneratedContent(el) {
11
+ function hasCSSGeneratedContent(el) {
12
12
  if (!el) return false;
13
13
 
14
14
  // Use getGeneratedContent and convert its result to a boolean
@@ -18,3 +18,7 @@ export function hasCSSGeneratedContent(el) {
18
18
  // We want to return true if content exists, false otherwise
19
19
  return content !== false;
20
20
  }
21
+
22
+ module.exports = {
23
+ hasCSSGeneratedContent
24
+ };
@@ -1,5 +1,5 @@
1
1
 
2
- import isHidden from './isHidden.js';
2
+ const isHidden = require('./isHidden.js');
3
3
 
4
4
  /**
5
5
  * Checks if the given element has a hidden parent element.
@@ -26,4 +26,4 @@ const hasHiddenParent = (element) => {
26
26
  return !visible;
27
27
  };
28
28
 
29
- export default hasHiddenParent;
29
+ module.exports = hasHiddenParent;
package/src/hasParent.js CHANGED
@@ -5,7 +5,7 @@
5
5
  * @param {string[]} selectors - An array of selectors to match against the element's parents.
6
6
  * @returns {boolean} - Returns true if the element has a parent that matches any of the selectors, otherwise false.
7
7
  */
8
- export function hasParent(element, selectors) {
8
+ function hasParent(element, selectors) {
9
9
  // Input validation
10
10
  if (!element || !(element instanceof Element)) {
11
11
  return false;
@@ -51,4 +51,8 @@ export function hasParent(element, selectors) {
51
51
  }
52
52
 
53
53
  return false;
54
+ }
55
+
56
+ module.exports = {
57
+ hasParent
54
58
  };
@@ -1,4 +1,4 @@
1
- import { isAriaAttributeValid } from './isAriaAttributesValid.js';
1
+ const { isAriaAttributeValid } = require('./isAriaAttributesValid.js');
2
2
 
3
3
  /**
4
4
  * Checks if an element has any valid ARIA attributes.
@@ -6,7 +6,7 @@ import { isAriaAttributeValid } from './isAriaAttributesValid.js';
6
6
  * @param {Element} element - The DOM element to check
7
7
  * @returns {boolean} True if the element has at least one valid ARIA attribute, false otherwise
8
8
  */
9
- export function hasValidAriaAttributes(element) {
9
+ function hasValidAriaAttributes(element) {
10
10
  if (!element || typeof element.hasAttributes !== 'function' || !element.attributes) {
11
11
  return false;
12
12
  }
@@ -28,3 +28,7 @@ export function hasValidAriaAttributes(element) {
28
28
 
29
29
  return false;
30
30
  }
31
+
32
+ module.exports = {
33
+ hasValidAriaAttributes
34
+ };
@@ -4,7 +4,7 @@
4
4
  * @param {HTMLElement} element - The DOM element to check.
5
5
  * @returns {boolean} True if the element has a valid ARIA role, false otherwise.
6
6
  */
7
- export function hasValidAriaRole(element) {
7
+ function hasValidAriaRole(element) {
8
8
  const validAriaRoles = new Set([
9
9
  "alert", "alertdialog", "button", "checkbox", "dialog", "gridcell", "link",
10
10
  "log", "marquee", "menuitem", "menuitemcheckbox", "menuitemradio", "option",
@@ -27,3 +27,7 @@ export function hasValidAriaRole(element) {
27
27
  const roles = roleAttr.trim().split(/\s+/);
28
28
  return validAriaRoles.has(roles[0]); // Only check the first role
29
29
  }
30
+
31
+ module.exports = {
32
+ hasValidAriaRole
33
+ };