@afixt/test-utils 1.2.0 → 1.2.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.
@@ -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
- beforeEach(() => {
6
- document.body.innerHTML = '';
7
-
8
- // Create a style element for pseudo-elements
9
- const style = document.createElement('style');
10
- style.innerHTML = `
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
- document.head.appendChild(style);
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
- beforeEach(() => {
142
- // Mock getComputedStyle to simulate real browser behavior
143
- originalGetComputedStyle = window.getComputedStyle;
36
+ it('should return false for null element', () => {
37
+ expect(getCSSGeneratedContent(null)).toBe(false);
144
38
  });
145
39
 
146
- afterEach(() => {
147
- // Restore original getComputedStyle
148
- window.getComputedStyle = originalGetComputedStyle;
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
- it('should handle quote removal in browser implementation', () => {
152
- // Mock getComputedStyle to return quoted content
153
- window.getComputedStyle = (el, pseudo) => ({
154
- getPropertyValue: (prop) => {
155
- if (prop === 'content' && pseudo === '::before') {
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
- it('should handle single quote removal in browser implementation', () => {
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
- it('should handle both before and after content with quotes', () => {
188
- window.getComputedStyle = (el, pseudo) => ({
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
- it('should handle after content with quotes', () => {
206
- window.getComputedStyle = (el, pseudo) => ({
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 handle content: none in browser implementation', () => {
223
- window.getComputedStyle = (el, pseudo) => ({
224
- getPropertyValue: (prop) => 'none'
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
- const div = document.createElement('div');
228
- Object.defineProperty(div, 'classList', { value: undefined });
229
- document.body.appendChild(div);
230
-
231
- expect(getCSSGeneratedContent(div)).toBe(false);
232
- });
64
+ // Mock getComputedStyle to return empty quoted content
65
+ const originalGetComputedStyle = window.getComputedStyle;
66
+ window.getComputedStyle = () => ({
67
+ getPropertyValue: () => '""',
68
+ });
233
69
 
234
- it('should handle content: normal in browser implementation', () => {
235
- window.getComputedStyle = (el, pseudo) => ({
236
- getPropertyValue: (prop) => 'normal'
237
- });
70
+ expect(getCSSGeneratedContent(div)).toBe(false);
238
71
 
239
- const div = document.createElement('div');
240
- Object.defineProperty(div, 'classList', { value: undefined });
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 handle empty quoted content', () => {
247
- window.getComputedStyle = (el, pseudo) => ({
248
- getPropertyValue: (prop) => {
249
- if (prop === 'content') {
250
- if (pseudo === '::before') return '""';
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
- it('should handle getComputedStyle error', () => {
264
- // Mock getComputedStyle to throw an error
265
- window.getComputedStyle = () => {
266
- throw new Error('getComputedStyle not supported');
267
- };
268
-
269
- const div = document.createElement('div');
270
- Object.defineProperty(div, 'classList', { value: undefined });
271
- document.body.appendChild(div);
272
-
273
- expect(getCSSGeneratedContent(div)).toBe(false);
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, vi } from 'vitest';
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
- beforeEach(() => {
12
- document.body.innerHTML = '';
13
- // Remove any added stylesheets
14
- const styleElements = document.querySelectorAll('style');
15
- styleElements.forEach(style => style.remove());
16
- vi.clearAllMocks();
17
- });
18
-
19
- // Helper function to create a stylesheet with CSS rules
20
- const addStyleToDocument = (cssRules) => {
21
- const styleElement = document.createElement('style');
22
- styleElement.textContent = cssRules;
23
- document.head.appendChild(styleElement);
24
- };
25
-
26
- it('should return true for elements with text content', () => {
27
- // Arrange
28
- const element = document.createElement('div');
29
- element.textContent = 'Text content';
30
- document.body.appendChild(element);
31
-
32
- // Act
33
- const result = hasCSSGeneratedContent(element);
34
-
35
- // Assert
36
- expect(result).toBe(true);
37
- });
38
-
39
- it('should return false for elements with no content', () => {
40
- // Arrange
41
- const element = document.createElement('div');
42
- document.body.appendChild(element);
43
-
44
- // Act
45
- const result = hasCSSGeneratedContent(element);
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
+ });