@afixt/test-utils 1.2.0 → 1.2.2
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/eslint.config.mjs +1 -1
- package/package.json +2 -1
- package/src/constants.js +231 -0
- package/src/cssUtils.js +77 -0
- package/src/domUtils.js +268 -12
- package/src/formUtils.js +175 -0
- package/src/getAccessibleText.js +60 -39
- package/src/getCSSGeneratedContent.js +39 -17
- package/src/index.js +18 -2
- package/src/stringUtils.js +149 -0
- package/src/tableUtils.js +180 -0
- package/src/testContrast.js +35 -1
- package/src/testLang.js +514 -444
- package/test/cssUtils.test.js +248 -0
- package/test/domUtils.test.js +815 -297
- package/test/formUtils.test.js +389 -0
- package/test/getAccessibleText.test.js +93 -0
- package/test/getCSSGeneratedContent.test.js +187 -232
- package/test/hasCSSGeneratedContent.test.js +37 -147
- package/test/playwright/css-pseudo-elements.spec.js +224 -91
- package/test/playwright/fixtures/css-pseudo-elements.html +6 -0
- package/test/stringUtils.test.js +222 -0
- package/test/tableUtils.test.js +340 -0
- package/vitest.config.js +28 -28
- package/test/getCSSGeneratedContent.browser.test.js +0 -125
|
@@ -2,12 +2,12 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
|
2
2
|
import { getCSSGeneratedContent } from '../src/getCSSGeneratedContent';
|
|
3
3
|
|
|
4
4
|
describe('getCSSGeneratedContent', () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
document.body.innerHTML = '';
|
|
7
|
+
|
|
8
|
+
// Create a style element for pseudo-elements
|
|
9
|
+
const style = document.createElement('style');
|
|
10
|
+
style.innerHTML = `
|
|
11
11
|
.with-before::before {
|
|
12
12
|
content: "Before Content";
|
|
13
13
|
}
|
|
@@ -30,247 +30,202 @@ describe('getCSSGeneratedContent', () => {
|
|
|
30
30
|
content: none;
|
|
31
31
|
}
|
|
32
32
|
`;
|
|
33
|
-
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should return false for null element', () => {
|
|
37
|
-
expect(getCSSGeneratedContent(null)).toBe(false);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should return false for elements with no generated content', () => {
|
|
41
|
-
const div = document.createElement('div');
|
|
42
|
-
document.body.appendChild(div);
|
|
43
|
-
|
|
44
|
-
// Mock getComputedStyle for this test since JSDOM doesn't support it
|
|
45
|
-
const originalGetComputedStyle = window.getComputedStyle;
|
|
46
|
-
window.getComputedStyle = () => ({
|
|
47
|
-
getPropertyValue: () => 'none'
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
51
|
-
|
|
52
|
-
// Restore original
|
|
53
|
-
window.getComputedStyle = originalGetComputedStyle;
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('should get ::before content', () => {
|
|
57
|
-
const div = document.createElement('div');
|
|
58
|
-
div.className = 'with-before';
|
|
59
|
-
document.body.appendChild(div);
|
|
60
|
-
|
|
61
|
-
expect(getCSSGeneratedContent(div, 'before')).toBe('Before Content');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should get ::after content', () => {
|
|
65
|
-
const div = document.createElement('div');
|
|
66
|
-
div.className = 'with-after';
|
|
67
|
-
document.body.appendChild(div);
|
|
68
|
-
|
|
69
|
-
expect(getCSSGeneratedContent(div, 'after')).toBe('After Content');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should get both ::before and ::after content', () => {
|
|
73
|
-
const div = document.createElement('div');
|
|
74
|
-
div.className = 'with-both';
|
|
75
|
-
document.body.appendChild(div);
|
|
76
|
-
|
|
77
|
-
expect(getCSSGeneratedContent(div)).toBe('Before Text After Text');
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('should get both content by default', () => {
|
|
81
|
-
const div = document.createElement('div');
|
|
82
|
-
div.className = 'with-both';
|
|
83
|
-
document.body.appendChild(div);
|
|
84
|
-
|
|
85
|
-
expect(getCSSGeneratedContent(div)).toBe(getCSSGeneratedContent(div, 'both'));
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('should handle quoted content', () => {
|
|
89
|
-
const div = document.createElement('div');
|
|
90
|
-
div.className = 'with-quotes';
|
|
91
|
-
document.body.appendChild(div);
|
|
92
|
-
|
|
93
|
-
expect(getCSSGeneratedContent(div, 'before')).toBe('Quoted Text');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('should return false for empty content', () => {
|
|
97
|
-
const div = document.createElement('div');
|
|
98
|
-
div.className = 'empty-content';
|
|
99
|
-
document.body.appendChild(div);
|
|
100
|
-
|
|
101
|
-
// Mock getComputedStyle to return empty quoted content
|
|
102
|
-
const originalGetComputedStyle = window.getComputedStyle;
|
|
103
|
-
window.getComputedStyle = () => ({
|
|
104
|
-
getPropertyValue: () => '""'
|
|
33
|
+
document.head.appendChild(style);
|
|
105
34
|
});
|
|
106
|
-
|
|
107
|
-
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
108
|
-
|
|
109
|
-
// Restore original
|
|
110
|
-
window.getComputedStyle = originalGetComputedStyle;
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('should return false for content: none', () => {
|
|
114
|
-
const div = document.createElement('div');
|
|
115
|
-
div.className = 'no-content';
|
|
116
|
-
document.body.appendChild(div);
|
|
117
|
-
|
|
118
|
-
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
it('should handle url content', () => {
|
|
122
|
-
const div = document.createElement('div');
|
|
123
|
-
div.className = 'url-content';
|
|
124
|
-
document.body.appendChild(div);
|
|
125
|
-
|
|
126
|
-
expect(getCSSGeneratedContent(div, 'before')).toBe('url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")');
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should handle undefined and non-string pseudoElement parameter', () => {
|
|
130
|
-
const div = document.createElement('div');
|
|
131
|
-
div.className = 'with-before';
|
|
132
|
-
document.body.appendChild(div);
|
|
133
|
-
|
|
134
|
-
// Should default to 'both' when no pseudoElement specified
|
|
135
|
-
expect(getCSSGeneratedContent(div, undefined)).toBe('Before Content');
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('Browser implementation paths', () => {
|
|
139
|
-
let originalGetComputedStyle;
|
|
140
35
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
originalGetComputedStyle = window.getComputedStyle;
|
|
36
|
+
it('should return false for null element', () => {
|
|
37
|
+
expect(getCSSGeneratedContent(null)).toBe(false);
|
|
144
38
|
});
|
|
145
39
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
});
|
|
40
|
+
it('should return false for elements with no generated content', () => {
|
|
41
|
+
const div = document.createElement('div');
|
|
42
|
+
document.body.appendChild(div);
|
|
150
43
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return '"Quoted Content"';
|
|
157
|
-
}
|
|
158
|
-
return 'none';
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
const div = document.createElement('div');
|
|
163
|
-
// Remove classList to bypass JSDOM check
|
|
164
|
-
Object.defineProperty(div, 'classList', { value: undefined });
|
|
165
|
-
document.body.appendChild(div);
|
|
166
|
-
|
|
167
|
-
expect(getCSSGeneratedContent(div, 'before')).toBe('Quoted Content');
|
|
168
|
-
});
|
|
44
|
+
// Mock getComputedStyle for this test since JSDOM doesn't support it
|
|
45
|
+
const originalGetComputedStyle = window.getComputedStyle;
|
|
46
|
+
window.getComputedStyle = () => ({
|
|
47
|
+
getPropertyValue: () => 'none',
|
|
48
|
+
});
|
|
169
49
|
|
|
170
|
-
|
|
171
|
-
window.getComputedStyle = (el, pseudo) => ({
|
|
172
|
-
getPropertyValue: (prop) => {
|
|
173
|
-
if (prop === 'content' && pseudo === '::before') {
|
|
174
|
-
return "'Single Quoted'";
|
|
175
|
-
}
|
|
176
|
-
return 'none';
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
const div = document.createElement('div');
|
|
181
|
-
Object.defineProperty(div, 'classList', { value: undefined });
|
|
182
|
-
document.body.appendChild(div);
|
|
183
|
-
|
|
184
|
-
expect(getCSSGeneratedContent(div, 'before')).toBe('Single Quoted');
|
|
185
|
-
});
|
|
50
|
+
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
186
51
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
getPropertyValue: (prop) => {
|
|
190
|
-
if (prop === 'content') {
|
|
191
|
-
if (pseudo === '::before') return '"Before"';
|
|
192
|
-
if (pseudo === '::after') return '"After"';
|
|
193
|
-
}
|
|
194
|
-
return 'none';
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
const div = document.createElement('div');
|
|
199
|
-
Object.defineProperty(div, 'classList', { value: undefined });
|
|
200
|
-
document.body.appendChild(div);
|
|
201
|
-
|
|
202
|
-
expect(getCSSGeneratedContent(div, 'both')).toBe('Before After');
|
|
52
|
+
// Restore original
|
|
53
|
+
window.getComputedStyle = originalGetComputedStyle;
|
|
203
54
|
});
|
|
204
55
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
getPropertyValue: (prop) => {
|
|
208
|
-
if (prop === 'content' && pseudo === '::after') {
|
|
209
|
-
return '"After Content"';
|
|
210
|
-
}
|
|
211
|
-
return 'none';
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
const div = document.createElement('div');
|
|
216
|
-
Object.defineProperty(div, 'classList', { value: undefined });
|
|
217
|
-
document.body.appendChild(div);
|
|
218
|
-
|
|
219
|
-
expect(getCSSGeneratedContent(div, 'after')).toBe('After Content');
|
|
220
|
-
});
|
|
56
|
+
// Tests for ::before, ::after, both, and quoted content require real browser
|
|
57
|
+
// CSS pseudo-element support. They run in Playwright: npm run test:playwright:css
|
|
221
58
|
|
|
222
|
-
it('should
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
59
|
+
it('should return false for empty content', () => {
|
|
60
|
+
const div = document.createElement('div');
|
|
61
|
+
div.className = 'empty-content';
|
|
62
|
+
document.body.appendChild(div);
|
|
226
63
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
});
|
|
64
|
+
// Mock getComputedStyle to return empty quoted content
|
|
65
|
+
const originalGetComputedStyle = window.getComputedStyle;
|
|
66
|
+
window.getComputedStyle = () => ({
|
|
67
|
+
getPropertyValue: () => '""',
|
|
68
|
+
});
|
|
233
69
|
|
|
234
|
-
|
|
235
|
-
window.getComputedStyle = (el, pseudo) => ({
|
|
236
|
-
getPropertyValue: (prop) => 'normal'
|
|
237
|
-
});
|
|
70
|
+
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
238
71
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
document.body.appendChild(div);
|
|
242
|
-
|
|
243
|
-
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
72
|
+
// Restore original
|
|
73
|
+
window.getComputedStyle = originalGetComputedStyle;
|
|
244
74
|
});
|
|
245
75
|
|
|
246
|
-
it('should
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return 'none';
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
const div = document.createElement('div');
|
|
257
|
-
Object.defineProperty(div, 'classList', { value: undefined });
|
|
258
|
-
document.body.appendChild(div);
|
|
259
|
-
|
|
260
|
-
expect(getCSSGeneratedContent(div, 'before')).toBe(false);
|
|
76
|
+
it('should return false for content: none', () => {
|
|
77
|
+
const div = document.createElement('div');
|
|
78
|
+
div.className = 'no-content';
|
|
79
|
+
document.body.appendChild(div);
|
|
80
|
+
|
|
81
|
+
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
261
82
|
});
|
|
262
83
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
84
|
+
// URL content and undefined pseudoElement tests require real browser
|
|
85
|
+
// CSS pseudo-element support. They run in Playwright: npm run test:playwright:css
|
|
86
|
+
|
|
87
|
+
describe('Browser implementation paths', () => {
|
|
88
|
+
let originalGetComputedStyle;
|
|
89
|
+
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
// Mock getComputedStyle to simulate real browser behavior
|
|
92
|
+
originalGetComputedStyle = window.getComputedStyle;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
afterEach(() => {
|
|
96
|
+
// Restore original getComputedStyle
|
|
97
|
+
window.getComputedStyle = originalGetComputedStyle;
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should handle quote removal in browser implementation', () => {
|
|
101
|
+
// Mock getComputedStyle to return quoted content
|
|
102
|
+
window.getComputedStyle = (el, pseudo) => ({
|
|
103
|
+
getPropertyValue: prop => {
|
|
104
|
+
if (prop === 'content' && pseudo === '::before') {
|
|
105
|
+
return '"Quoted Content"';
|
|
106
|
+
}
|
|
107
|
+
return 'none';
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const div = document.createElement('div');
|
|
112
|
+
// Remove classList to bypass JSDOM check
|
|
113
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
114
|
+
document.body.appendChild(div);
|
|
115
|
+
|
|
116
|
+
expect(getCSSGeneratedContent(div, 'before')).toBe('Quoted Content');
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should handle single quote removal in browser implementation', () => {
|
|
120
|
+
window.getComputedStyle = (el, pseudo) => ({
|
|
121
|
+
getPropertyValue: prop => {
|
|
122
|
+
if (prop === 'content' && pseudo === '::before') {
|
|
123
|
+
return "'Single Quoted'";
|
|
124
|
+
}
|
|
125
|
+
return 'none';
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const div = document.createElement('div');
|
|
130
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
131
|
+
document.body.appendChild(div);
|
|
132
|
+
|
|
133
|
+
expect(getCSSGeneratedContent(div, 'before')).toBe('Single Quoted');
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should handle both before and after content with quotes', () => {
|
|
137
|
+
window.getComputedStyle = (el, pseudo) => ({
|
|
138
|
+
getPropertyValue: prop => {
|
|
139
|
+
if (prop === 'content') {
|
|
140
|
+
if (pseudo === '::before') {
|
|
141
|
+
return '"Before"';
|
|
142
|
+
}
|
|
143
|
+
if (pseudo === '::after') {
|
|
144
|
+
return '"After"';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return 'none';
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const div = document.createElement('div');
|
|
152
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
153
|
+
document.body.appendChild(div);
|
|
154
|
+
|
|
155
|
+
expect(getCSSGeneratedContent(div, 'both')).toBe('Before After');
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should handle after content with quotes', () => {
|
|
159
|
+
window.getComputedStyle = (el, pseudo) => ({
|
|
160
|
+
getPropertyValue: prop => {
|
|
161
|
+
if (prop === 'content' && pseudo === '::after') {
|
|
162
|
+
return '"After Content"';
|
|
163
|
+
}
|
|
164
|
+
return 'none';
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const div = document.createElement('div');
|
|
169
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
170
|
+
document.body.appendChild(div);
|
|
171
|
+
|
|
172
|
+
expect(getCSSGeneratedContent(div, 'after')).toBe('After Content');
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should handle content: none in browser implementation', () => {
|
|
176
|
+
window.getComputedStyle = (_el, _pseudo) => ({
|
|
177
|
+
getPropertyValue: _prop => 'none',
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const div = document.createElement('div');
|
|
181
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
182
|
+
document.body.appendChild(div);
|
|
183
|
+
|
|
184
|
+
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should handle content: normal in browser implementation', () => {
|
|
188
|
+
window.getComputedStyle = (_el, _pseudo) => ({
|
|
189
|
+
getPropertyValue: _prop => 'normal',
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
const div = document.createElement('div');
|
|
193
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
194
|
+
document.body.appendChild(div);
|
|
195
|
+
|
|
196
|
+
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should handle empty quoted content', () => {
|
|
200
|
+
window.getComputedStyle = (el, pseudo) => ({
|
|
201
|
+
getPropertyValue: prop => {
|
|
202
|
+
if (prop === 'content') {
|
|
203
|
+
if (pseudo === '::before') {
|
|
204
|
+
return '""';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return 'none';
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const div = document.createElement('div');
|
|
212
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
213
|
+
document.body.appendChild(div);
|
|
214
|
+
|
|
215
|
+
expect(getCSSGeneratedContent(div, 'before')).toBe(false);
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should handle getComputedStyle error', () => {
|
|
219
|
+
// Mock getComputedStyle to throw an error
|
|
220
|
+
window.getComputedStyle = () => {
|
|
221
|
+
throw new Error('getComputedStyle not supported');
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const div = document.createElement('div');
|
|
225
|
+
Object.defineProperty(div, 'classList', { value: undefined });
|
|
226
|
+
document.body.appendChild(div);
|
|
227
|
+
|
|
228
|
+
expect(getCSSGeneratedContent(div)).toBe(false);
|
|
229
|
+
});
|
|
274
230
|
});
|
|
275
|
-
|
|
276
|
-
});
|
|
231
|
+
});
|
|
@@ -1,150 +1,40 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
2
|
import { hasCSSGeneratedContent } from '../src/hasCSSGeneratedContent.js';
|
|
3
|
-
import * as getGeneratedContentModule from '../src/getGeneratedContent.js';
|
|
4
|
-
|
|
5
|
-
// Helper to detect if we're running in a real browser or JSDOM
|
|
6
|
-
const isJsdom = typeof window !== 'undefined' &&
|
|
7
|
-
window.navigator &&
|
|
8
|
-
/jsdom|node/i.test(window.navigator.userAgent);
|
|
9
3
|
|
|
10
4
|
describe('hasCSSGeneratedContent', () => {
|
|
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
|
-
// Assert
|
|
48
|
-
expect(result).toBe(false);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should return false for null or undefined elements', () => {
|
|
52
|
-
// Act & Assert
|
|
53
|
-
expect(hasCSSGeneratedContent(null)).toBe(false);
|
|
54
|
-
expect(hasCSSGeneratedContent(undefined)).toBe(false);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it('should return true for elements with whitespace-only text content', () => {
|
|
58
|
-
// Arrange
|
|
59
|
-
const element = document.createElement('div');
|
|
60
|
-
element.textContent = ' ';
|
|
61
|
-
document.body.appendChild(element);
|
|
62
|
-
|
|
63
|
-
// Act
|
|
64
|
-
const result = hasCSSGeneratedContent(element);
|
|
65
|
-
|
|
66
|
-
// Assert
|
|
67
|
-
expect(result).toBe(true);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// The following tests rely on proper implementation of getGeneratedContent
|
|
71
|
-
// and may need to be run in a real browser environment for CSS pseudo-elements
|
|
72
|
-
// Skip these tests in JSDOM environment as it doesn't support getComputedStyle for pseudo-elements
|
|
73
|
-
|
|
74
|
-
(isJsdom ? it.skip : it)('should correctly identify elements with ::before content', () => {
|
|
75
|
-
// Arrange
|
|
76
|
-
const element = document.createElement('div');
|
|
77
|
-
element.id = 'with-before';
|
|
78
|
-
document.body.appendChild(element);
|
|
79
|
-
|
|
80
|
-
// Mock getGeneratedContent to simulate browser behavior
|
|
81
|
-
const spy = vi.spyOn(getGeneratedContentModule, 'getGeneratedContent');
|
|
82
|
-
spy.mockImplementation(() => 'Before content');
|
|
83
|
-
|
|
84
|
-
// Act
|
|
85
|
-
const result = hasCSSGeneratedContent(element);
|
|
86
|
-
|
|
87
|
-
// Assert
|
|
88
|
-
expect(result).toBe(true);
|
|
89
|
-
|
|
90
|
-
// Clean up
|
|
91
|
-
spy.mockRestore();
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
(isJsdom ? it.skip : it)('should correctly identify elements with ::after content', () => {
|
|
95
|
-
// Arrange
|
|
96
|
-
const element = document.createElement('div');
|
|
97
|
-
element.id = 'with-after';
|
|
98
|
-
document.body.appendChild(element);
|
|
99
|
-
|
|
100
|
-
// Mock getGeneratedContent to simulate browser behavior
|
|
101
|
-
const spy = vi.spyOn(getGeneratedContentModule, 'getGeneratedContent');
|
|
102
|
-
spy.mockImplementation(() => 'After content');
|
|
103
|
-
|
|
104
|
-
// Act
|
|
105
|
-
const result = hasCSSGeneratedContent(element);
|
|
106
|
-
|
|
107
|
-
// Assert
|
|
108
|
-
expect(result).toBe(true);
|
|
109
|
-
|
|
110
|
-
// Clean up
|
|
111
|
-
spy.mockRestore();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should return false when getGeneratedContent returns false', () => {
|
|
115
|
-
// Arrange
|
|
116
|
-
const element = document.createElement('div');
|
|
117
|
-
|
|
118
|
-
// Mock getGeneratedContent to simulate no content
|
|
119
|
-
const spy = vi.spyOn(getGeneratedContentModule, 'getGeneratedContent');
|
|
120
|
-
spy.mockImplementation(() => false);
|
|
121
|
-
|
|
122
|
-
// Act
|
|
123
|
-
const result = hasCSSGeneratedContent(element);
|
|
124
|
-
|
|
125
|
-
// Assert
|
|
126
|
-
expect(result).toBe(false);
|
|
127
|
-
|
|
128
|
-
// Clean up
|
|
129
|
-
spy.mockRestore();
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should handle complex cases with mixed content', () => {
|
|
133
|
-
// Arrange
|
|
134
|
-
const element = document.createElement('div');
|
|
135
|
-
element.textContent = 'Text';
|
|
136
|
-
|
|
137
|
-
// Mock getGeneratedContent to simulate mixed content
|
|
138
|
-
const spy = vi.spyOn(getGeneratedContentModule, 'getGeneratedContent');
|
|
139
|
-
spy.mockImplementation(() => 'Before Text After');
|
|
140
|
-
|
|
141
|
-
// Act
|
|
142
|
-
const result = hasCSSGeneratedContent(element);
|
|
143
|
-
|
|
144
|
-
// Assert
|
|
145
|
-
expect(result).toBe(true);
|
|
146
|
-
|
|
147
|
-
// Clean up
|
|
148
|
-
spy.mockRestore();
|
|
149
|
-
});
|
|
150
|
-
});
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
document.body.innerHTML = '';
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('should return false for null or undefined elements', () => {
|
|
10
|
+
expect(hasCSSGeneratedContent(null)).toBe(false);
|
|
11
|
+
expect(hasCSSGeneratedContent(undefined)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should return false for elements with no content', () => {
|
|
15
|
+
const element = document.createElement('div');
|
|
16
|
+
document.body.appendChild(element);
|
|
17
|
+
|
|
18
|
+
expect(hasCSSGeneratedContent(element)).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return false for elements with only text content (no CSS generated content)', () => {
|
|
22
|
+
const element = document.createElement('div');
|
|
23
|
+
element.textContent = 'Text content';
|
|
24
|
+
document.body.appendChild(element);
|
|
25
|
+
|
|
26
|
+
// hasCSSGeneratedContent only checks CSS pseudo-elements, not textContent
|
|
27
|
+
expect(hasCSSGeneratedContent(element)).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should return false for elements with whitespace-only text content', () => {
|
|
31
|
+
const element = document.createElement('div');
|
|
32
|
+
element.textContent = ' ';
|
|
33
|
+
document.body.appendChild(element);
|
|
34
|
+
|
|
35
|
+
expect(hasCSSGeneratedContent(element)).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Tests for actual CSS pseudo-element detection require a real browser.
|
|
39
|
+
// They run in Playwright: npm run test:playwright:css
|
|
40
|
+
});
|