Skip to content

Commit 1a51ca9

Browse files
committed
refactor: fix axe
1 parent 933daf1 commit 1a51ca9

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

packages/plugin-axe/src/lib/meta/transform.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
CATEGORY_GROUPS,
88
getWcagPresetTags,
99
} from '../groups.js';
10+
import '../polyfills.dom.js';
1011

1112
/** Loads Axe rules filtered by the specified preset. */
1213
export function loadAxeRules(preset: AxePreset): axe.RuleMetadata[] {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Polyfills for axe-core DOM access in Node.js environment
2+
// This must be imported before any axe-core imports
3+
4+
if (typeof global.window === 'undefined') {
5+
const mockElement = {
6+
style: {},
7+
addEventListener: () => {},
8+
removeEventListener: () => {},
9+
appendChild: () => {},
10+
setAttribute: () => {},
11+
getAttribute: () => null,
12+
textContent: '',
13+
innerHTML: '',
14+
className: '',
15+
id: '',
16+
tagName: 'DIV',
17+
parentNode: null,
18+
childNodes: [],
19+
firstChild: null,
20+
lastChild: null,
21+
nextSibling: null,
22+
previousSibling: null,
23+
ownerDocument: null,
24+
};
25+
26+
// Mock document
27+
const mockDocument = {
28+
createElement: tagName => ({
29+
...mockElement,
30+
tagName: tagName.toUpperCase(),
31+
}),
32+
createElementNS: (ns, tagName) => ({
33+
...mockElement,
34+
tagName: tagName.toUpperCase(),
35+
}),
36+
createTextNode: text => ({ ...mockElement, textContent: text }),
37+
body: { ...mockElement, tagName: 'BODY' },
38+
documentElement: { ...mockElement, tagName: 'HTML' },
39+
head: { ...mockElement, tagName: 'HEAD' },
40+
addEventListener: () => {},
41+
removeEventListener: () => {},
42+
querySelector: () => null,
43+
querySelectorAll: () => [],
44+
getElementById: () => null,
45+
getElementsByTagName: () => [mockElement],
46+
getElementsByClassName: () => [],
47+
createDocumentFragment: () => ({}),
48+
createComment: () => ({}),
49+
implementation: {
50+
createHTMLDocument: () => mockDocument,
51+
},
52+
};
53+
54+
// Set up global objects
55+
global.window = global;
56+
global.document = mockDocument;
57+
58+
// Only set navigator if it doesn't exist or isn't read-only
59+
try {
60+
if (typeof global.navigator === 'undefined') {
61+
global.navigator = {
62+
userAgent: 'Node.js',
63+
platform: 'Node.js',
64+
appVersion: 'Node.js',
65+
};
66+
}
67+
} catch (e) {
68+
// navigator is read-only, skip setting it
69+
}
70+
71+
// Also set on globalThis for consistency
72+
globalThis.window = global.window;
73+
globalThis.document = global.document;
74+
try {
75+
if (typeof globalThis.navigator === 'undefined') {
76+
globalThis.navigator = global.navigator;
77+
}
78+
} catch (e) {
79+
// navigator is read-only, skip setting it
80+
}
81+
}

0 commit comments

Comments
 (0)