@keenthemes/ktui 1.0.19 → 1.0.21
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/dist/ktui.js +690 -166
- package/dist/ktui.min.js +1 -1
- package/dist/ktui.min.js.map +1 -1
- package/dist/styles.css +165 -31
- package/examples/image-input/file-upload-example.html +189 -0
- package/examples/select/remote-data_.html +5 -0
- package/examples/select/test-optimizations.html +227 -0
- package/examples/select/test-remote-search.html +151 -0
- package/examples/sticky/README.md +158 -0
- package/examples/sticky/debug-sticky.html +144 -0
- package/examples/sticky/test-runner.html +175 -0
- package/examples/sticky/test-sticky-logic.js +369 -0
- package/examples/sticky/test-sticky-positioning.html +386 -0
- package/examples/toast/example.html +52 -0
- package/lib/cjs/components/component.js +59 -5
- package/lib/cjs/components/component.js.map +1 -1
- package/lib/cjs/components/datatable/datatable-sort.js +4 -0
- package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
- package/lib/cjs/components/datatable/datatable.js +79 -12
- package/lib/cjs/components/datatable/datatable.js.map +1 -1
- package/lib/cjs/components/image-input/image-input.js +10 -2
- package/lib/cjs/components/image-input/image-input.js.map +1 -1
- package/lib/cjs/components/select/combobox.js +50 -20
- package/lib/cjs/components/select/combobox.js.map +1 -1
- package/lib/cjs/components/select/config.js +1 -0
- package/lib/cjs/components/select/config.js.map +1 -1
- package/lib/cjs/components/select/dropdown.js +4 -2
- package/lib/cjs/components/select/dropdown.js.map +1 -1
- package/lib/cjs/components/select/index.js.map +1 -1
- package/lib/cjs/components/select/option.js +2 -1
- package/lib/cjs/components/select/option.js.map +1 -1
- package/lib/cjs/components/select/remote.js +50 -50
- package/lib/cjs/components/select/remote.js.map +1 -1
- package/lib/cjs/components/select/search.js +15 -5
- package/lib/cjs/components/select/search.js.map +1 -1
- package/lib/cjs/components/select/select.js +273 -32
- package/lib/cjs/components/select/select.js.map +1 -1
- package/lib/cjs/components/select/tags.js +3 -1
- package/lib/cjs/components/select/tags.js.map +1 -1
- package/lib/cjs/components/select/templates.js +6 -0
- package/lib/cjs/components/select/templates.js.map +1 -1
- package/lib/cjs/components/select/utils.js +23 -10
- package/lib/cjs/components/select/utils.js.map +1 -1
- package/lib/cjs/components/stepper/stepper.js +59 -12
- package/lib/cjs/components/stepper/stepper.js.map +1 -1
- package/lib/cjs/components/sticky/sticky.js +52 -14
- package/lib/cjs/components/sticky/sticky.js.map +1 -1
- package/lib/esm/components/component.js +59 -5
- package/lib/esm/components/component.js.map +1 -1
- package/lib/esm/components/datatable/datatable-sort.js +4 -0
- package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
- package/lib/esm/components/datatable/datatable.js +78 -12
- package/lib/esm/components/datatable/datatable.js.map +1 -1
- package/lib/esm/components/image-input/image-input.js +10 -2
- package/lib/esm/components/image-input/image-input.js.map +1 -1
- package/lib/esm/components/select/combobox.js +50 -20
- package/lib/esm/components/select/combobox.js.map +1 -1
- package/lib/esm/components/select/config.js +1 -0
- package/lib/esm/components/select/config.js.map +1 -1
- package/lib/esm/components/select/dropdown.js +4 -2
- package/lib/esm/components/select/dropdown.js.map +1 -1
- package/lib/esm/components/select/index.js +1 -1
- package/lib/esm/components/select/index.js.map +1 -1
- package/lib/esm/components/select/option.js +2 -1
- package/lib/esm/components/select/option.js.map +1 -1
- package/lib/esm/components/select/remote.js +50 -50
- package/lib/esm/components/select/remote.js.map +1 -1
- package/lib/esm/components/select/search.js +16 -6
- package/lib/esm/components/select/search.js.map +1 -1
- package/lib/esm/components/select/select.js +273 -32
- package/lib/esm/components/select/select.js.map +1 -1
- package/lib/esm/components/select/tags.js +3 -1
- package/lib/esm/components/select/tags.js.map +1 -1
- package/lib/esm/components/select/templates.js +6 -0
- package/lib/esm/components/select/templates.js.map +1 -1
- package/lib/esm/components/select/utils.js +23 -10
- package/lib/esm/components/select/utils.js.map +1 -1
- package/lib/esm/components/stepper/stepper.js +59 -12
- package/lib/esm/components/stepper/stepper.js.map +1 -1
- package/lib/esm/components/sticky/sticky.js +52 -14
- package/lib/esm/components/sticky/sticky.js.map +1 -1
- package/package.json +2 -2
- package/src/components/component.ts +19 -4
- package/src/components/datatable/datatable-sort.ts +6 -0
- package/src/components/datatable/datatable.ts +98 -15
- package/src/components/datatable/types.ts +5 -1
- package/src/components/image-input/image-input.ts +11 -2
- package/src/components/image-input/types.ts +1 -0
- package/src/components/input/input-group.css +1 -1
- package/src/components/input/input.css +1 -1
- package/src/components/scrollable/scrollable.css +3 -3
- package/src/components/select/combobox.ts +84 -34
- package/src/components/select/config.ts +2 -0
- package/src/components/select/dropdown.ts +20 -11
- package/src/components/select/index.ts +6 -1
- package/src/components/select/option.ts +7 -6
- package/src/components/select/remote.ts +51 -52
- package/src/components/select/search.ts +59 -44
- package/src/components/select/select.css +26 -17
- package/src/components/select/select.ts +472 -101
- package/src/components/select/tags.ts +9 -3
- package/src/components/select/templates.ts +10 -0
- package/src/components/select/utils.ts +55 -20
- package/src/components/select/variants.css +0 -1
- package/src/components/stepper/stepper.ts +2 -2
- package/src/components/sticky/sticky.ts +47 -16
- package/src/components/sticky/types.ts +3 -0
- package/src/components/table/table.css +1 -1
- package/src/components/textarea/textarea.css +1 -1
- package/src/components/toast/toast.css +84 -47
- package/src/components/toast/types.ts +3 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KTUI Sticky Component - Logic Test
|
|
3
|
+
* Tests the positioning logic changes from PR #27
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { KTSticky } from '../../lib/esm/components/sticky/index.js';
|
|
7
|
+
|
|
8
|
+
class StickyTestSuite {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.testResults = [];
|
|
11
|
+
this.testElement = null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Setup test environment
|
|
15
|
+
setup() {
|
|
16
|
+
// Create a test container
|
|
17
|
+
const container = document.createElement('div');
|
|
18
|
+
container.id = 'sticky-test-container';
|
|
19
|
+
container.style.cssText = `
|
|
20
|
+
position: relative;
|
|
21
|
+
width: 100%;
|
|
22
|
+
height: 200vh;
|
|
23
|
+
background: #f0f0f0;
|
|
24
|
+
padding: 20px;
|
|
25
|
+
`;
|
|
26
|
+
document.body.appendChild(container);
|
|
27
|
+
|
|
28
|
+
// Create test element
|
|
29
|
+
this.testElement = document.createElement('div');
|
|
30
|
+
this.testElement.id = 'sticky-test-element';
|
|
31
|
+
this.testElement.style.cssText = `
|
|
32
|
+
width: 200px;
|
|
33
|
+
height: 100px;
|
|
34
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
35
|
+
color: white;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
font-weight: bold;
|
|
40
|
+
border-radius: 8px;
|
|
41
|
+
`;
|
|
42
|
+
container.appendChild(this.testElement);
|
|
43
|
+
|
|
44
|
+
console.log('✅ Test environment setup complete');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Cleanup test environment
|
|
48
|
+
cleanup() {
|
|
49
|
+
const container = document.getElementById('sticky-test-container');
|
|
50
|
+
if (container) {
|
|
51
|
+
container.remove();
|
|
52
|
+
}
|
|
53
|
+
this.testResults = [];
|
|
54
|
+
console.log('✅ Test environment cleaned up');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Test helper: create sticky instance with config
|
|
58
|
+
createStickyInstance(config) {
|
|
59
|
+
// Remove existing instance
|
|
60
|
+
if (this.testElement.hasAttribute('data-kt-sticky-initialized')) {
|
|
61
|
+
const existingInstance = KTSticky.getInstance(this.testElement);
|
|
62
|
+
if (existingInstance) {
|
|
63
|
+
// Force cleanup
|
|
64
|
+
this.testElement.classList.remove('active');
|
|
65
|
+
this.testElement.style.position = '';
|
|
66
|
+
this.testElement.style.top = '';
|
|
67
|
+
this.testElement.style.bottom = '';
|
|
68
|
+
this.testElement.style.left = '';
|
|
69
|
+
this.testElement.style.right = '';
|
|
70
|
+
this.testElement.style.insetBlockStart = '';
|
|
71
|
+
this.testElement.style.insetInlineStart = '';
|
|
72
|
+
this.testElement.style.insetInlineEnd = '';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Clear attributes
|
|
77
|
+
this.testElement.removeAttribute('data-kt-sticky');
|
|
78
|
+
this.testElement.removeAttribute('data-kt-sticky-top');
|
|
79
|
+
this.testElement.removeAttribute('data-kt-sticky-bottom');
|
|
80
|
+
this.testElement.removeAttribute('data-kt-sticky-start');
|
|
81
|
+
this.testElement.removeAttribute('data-kt-sticky-end');
|
|
82
|
+
this.testElement.removeAttribute('data-kt-sticky-middle');
|
|
83
|
+
this.testElement.removeAttribute('data-kt-sticky-center');
|
|
84
|
+
this.testElement.removeAttribute('data-kt-sticky-name');
|
|
85
|
+
|
|
86
|
+
// Set new attributes based on config
|
|
87
|
+
this.testElement.setAttribute('data-kt-sticky', 'true');
|
|
88
|
+
this.testElement.setAttribute('data-kt-sticky-name', 'test');
|
|
89
|
+
|
|
90
|
+
if (config.top !== undefined) this.testElement.setAttribute('data-kt-sticky-top', config.top);
|
|
91
|
+
if (config.bottom !== undefined) this.testElement.setAttribute('data-kt-sticky-bottom', config.bottom);
|
|
92
|
+
if (config.start !== undefined) this.testElement.setAttribute('data-kt-sticky-start', config.start);
|
|
93
|
+
if (config.end !== undefined) this.testElement.setAttribute('data-kt-sticky-end', config.end);
|
|
94
|
+
if (config.middle !== undefined) this.testElement.setAttribute('data-kt-sticky-middle', config.middle);
|
|
95
|
+
if (config.center !== undefined) this.testElement.setAttribute('data-kt-sticky-center', config.center);
|
|
96
|
+
|
|
97
|
+
// Create new instance
|
|
98
|
+
return new KTSticky(this.testElement);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Test helper: get computed styles
|
|
102
|
+
getComputedStyles() {
|
|
103
|
+
const computed = window.getComputedStyle(this.testElement);
|
|
104
|
+
return {
|
|
105
|
+
position: computed.position,
|
|
106
|
+
top: computed.top,
|
|
107
|
+
bottom: computed.bottom,
|
|
108
|
+
left: computed.left,
|
|
109
|
+
right: computed.right,
|
|
110
|
+
insetBlockStart: computed.insetBlockStart,
|
|
111
|
+
insetBlockEnd: computed.insetBlockEnd,
|
|
112
|
+
insetInlineStart: computed.insetInlineStart,
|
|
113
|
+
insetInlineEnd: computed.insetInlineEnd,
|
|
114
|
+
transform: computed.transform
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Test helper: simulate scroll to trigger sticky
|
|
119
|
+
simulateScroll() {
|
|
120
|
+
// Simulate scroll by triggering the scroll event
|
|
121
|
+
window.dispatchEvent(new Event('scroll'));
|
|
122
|
+
|
|
123
|
+
// Force a small delay to allow processing
|
|
124
|
+
return new Promise(resolve => setTimeout(resolve, 100));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Test 1: Middle positioning
|
|
128
|
+
async testMiddlePositioning() {
|
|
129
|
+
console.log('🧪 Testing Middle (Vertical Center) Positioning...');
|
|
130
|
+
|
|
131
|
+
const instance = this.createStickyInstance({ middle: true });
|
|
132
|
+
await this.simulateScroll();
|
|
133
|
+
|
|
134
|
+
const styles = this.getComputedStyles();
|
|
135
|
+
const isMiddle = styles.insetBlockStart === '50%';
|
|
136
|
+
|
|
137
|
+
this.testResults.push({
|
|
138
|
+
test: 'Middle Positioning',
|
|
139
|
+
passed: isMiddle,
|
|
140
|
+
expected: 'insetBlockStart: 50%',
|
|
141
|
+
actual: `insetBlockStart: ${styles.insetBlockStart}`,
|
|
142
|
+
styles
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
console.log(isMiddle ? '✅ Middle positioning works' : '❌ Middle positioning failed');
|
|
146
|
+
return isMiddle;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Test 2: Center positioning
|
|
150
|
+
async testCenterPositioning() {
|
|
151
|
+
console.log('🧪 Testing Center (Horizontal Center) Positioning...');
|
|
152
|
+
|
|
153
|
+
const instance = this.createStickyInstance({ center: true });
|
|
154
|
+
await this.simulateScroll();
|
|
155
|
+
|
|
156
|
+
const styles = this.getComputedStyles();
|
|
157
|
+
const isCenter = styles.insetInlineStart === '50%';
|
|
158
|
+
|
|
159
|
+
this.testResults.push({
|
|
160
|
+
test: 'Center Positioning',
|
|
161
|
+
passed: isCenter,
|
|
162
|
+
expected: 'insetInlineStart: 50%',
|
|
163
|
+
actual: `insetInlineStart: ${styles.insetInlineStart}`,
|
|
164
|
+
styles
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
console.log(isCenter ? '✅ Center positioning works' : '❌ Center positioning failed');
|
|
168
|
+
return isCenter;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Test 3: Middle + Center positioning
|
|
172
|
+
async testMiddleCenterPositioning() {
|
|
173
|
+
console.log('🧪 Testing Middle + Center (Fully Centered) Positioning...');
|
|
174
|
+
|
|
175
|
+
const instance = this.createStickyInstance({ middle: true, center: true });
|
|
176
|
+
await this.simulateScroll();
|
|
177
|
+
|
|
178
|
+
const styles = this.getComputedStyles();
|
|
179
|
+
const isMiddleCenter = styles.insetBlockStart === '50%' && styles.insetInlineStart === '50%';
|
|
180
|
+
|
|
181
|
+
this.testResults.push({
|
|
182
|
+
test: 'Middle + Center Positioning',
|
|
183
|
+
passed: isMiddleCenter,
|
|
184
|
+
expected: 'insetBlockStart: 50%, insetInlineStart: 50%',
|
|
185
|
+
actual: `insetBlockStart: ${styles.insetBlockStart}, insetInlineStart: ${styles.insetInlineStart}`,
|
|
186
|
+
styles
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
console.log(isMiddleCenter ? '✅ Middle + Center positioning works' : '❌ Middle + Center positioning failed');
|
|
190
|
+
return isMiddleCenter;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Test 4: Bottom positioning
|
|
194
|
+
async testBottomPositioning() {
|
|
195
|
+
console.log('🧪 Testing Bottom Positioning...');
|
|
196
|
+
|
|
197
|
+
const instance = this.createStickyInstance({ bottom: '20' });
|
|
198
|
+
await this.simulateScroll();
|
|
199
|
+
|
|
200
|
+
const styles = this.getComputedStyles();
|
|
201
|
+
const isBottom = styles.insetBlockEnd === '20px';
|
|
202
|
+
|
|
203
|
+
this.testResults.push({
|
|
204
|
+
test: 'Bottom Positioning',
|
|
205
|
+
passed: isBottom,
|
|
206
|
+
expected: 'insetBlockEnd: 20px',
|
|
207
|
+
actual: `insetBlockEnd: ${styles.insetBlockEnd}`,
|
|
208
|
+
styles
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
console.log(isBottom ? '✅ Bottom positioning works' : '❌ Bottom positioning failed');
|
|
212
|
+
return isBottom;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Test 5: Auto positioning with offset calculation
|
|
216
|
+
async testAutoPositioning() {
|
|
217
|
+
console.log('🧪 Testing Auto Positioning with Offset Calculation...');
|
|
218
|
+
|
|
219
|
+
const instance = this.createStickyInstance({ start: 'auto', top: '50' });
|
|
220
|
+
await this.simulateScroll();
|
|
221
|
+
|
|
222
|
+
const styles = this.getComputedStyles();
|
|
223
|
+
const hasAutoOffset = styles.insetInlineStart !== 'auto' && styles.insetInlineStart !== '';
|
|
224
|
+
|
|
225
|
+
this.testResults.push({
|
|
226
|
+
test: 'Auto Positioning with Offset',
|
|
227
|
+
passed: hasAutoOffset,
|
|
228
|
+
expected: 'insetInlineStart: calculated offset value',
|
|
229
|
+
actual: `insetInlineStart: ${styles.insetInlineStart}`,
|
|
230
|
+
styles
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
console.log(hasAutoOffset ? '✅ Auto positioning with offset works' : '❌ Auto positioning with offset failed');
|
|
234
|
+
return hasAutoOffset;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Test 6: Exclusive positioning logic (top vs bottom)
|
|
238
|
+
async testExclusivePositioning() {
|
|
239
|
+
console.log('🧪 Testing Exclusive Positioning Logic (top vs bottom)...');
|
|
240
|
+
|
|
241
|
+
const instance = this.createStickyInstance({ top: '30', bottom: '30' });
|
|
242
|
+
await this.simulateScroll();
|
|
243
|
+
|
|
244
|
+
const styles = this.getComputedStyles();
|
|
245
|
+
const isExclusive = styles.insetBlockStart === '30px' && styles.insetBlockEnd === 'auto';
|
|
246
|
+
|
|
247
|
+
this.testResults.push({
|
|
248
|
+
test: 'Exclusive Positioning Logic',
|
|
249
|
+
passed: isExclusive,
|
|
250
|
+
expected: 'insetBlockStart: 30px, insetBlockEnd: auto (top takes precedence)',
|
|
251
|
+
actual: `insetBlockStart: ${styles.insetBlockStart}, insetBlockEnd: ${styles.insetBlockEnd}`,
|
|
252
|
+
styles
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
console.log(isExclusive ? '✅ Exclusive positioning logic works' : '❌ Exclusive positioning logic failed');
|
|
256
|
+
return isExclusive;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Test 7: Logical properties for RTL support
|
|
260
|
+
async testLogicalProperties() {
|
|
261
|
+
console.log('🧪 Testing Logical Properties for RTL Support...');
|
|
262
|
+
|
|
263
|
+
const instance = this.createStickyInstance({ end: '20', top: '40' });
|
|
264
|
+
await this.simulateScroll();
|
|
265
|
+
|
|
266
|
+
const styles = this.getComputedStyles();
|
|
267
|
+
const usesLogicalProps = styles.insetInlineEnd === '20px' && styles.insetBlockStart === '40px';
|
|
268
|
+
|
|
269
|
+
this.testResults.push({
|
|
270
|
+
test: 'Logical Properties (RTL Support)',
|
|
271
|
+
passed: usesLogicalProps,
|
|
272
|
+
expected: 'insetInlineEnd: 20px, insetBlockStart: 40px',
|
|
273
|
+
actual: `insetInlineEnd: ${styles.insetInlineEnd}, insetBlockStart: ${styles.insetBlockStart}`,
|
|
274
|
+
styles
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
console.log(usesLogicalProps ? '✅ Logical properties work' : '❌ Logical properties failed');
|
|
278
|
+
return usesLogicalProps;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Test 8: Auto fallback values
|
|
282
|
+
async testAutoFallbackValues() {
|
|
283
|
+
console.log('🧪 Testing Auto Fallback Values...');
|
|
284
|
+
|
|
285
|
+
const instance = this.createStickyInstance({ top: 'auto' });
|
|
286
|
+
await this.simulateScroll();
|
|
287
|
+
|
|
288
|
+
const styles = this.getComputedStyles();
|
|
289
|
+
const hasAutoFallback = styles.insetBlockStart === '0px';
|
|
290
|
+
|
|
291
|
+
this.testResults.push({
|
|
292
|
+
test: 'Auto Fallback Values',
|
|
293
|
+
passed: hasAutoFallback,
|
|
294
|
+
expected: 'insetBlockStart: 0px (auto defaults to 0px)',
|
|
295
|
+
actual: `insetBlockStart: ${styles.insetBlockStart}`,
|
|
296
|
+
styles
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
console.log(hasAutoFallback ? '✅ Auto fallback values work' : '❌ Auto fallback values failed');
|
|
300
|
+
return hasAutoFallback;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Run all tests
|
|
304
|
+
async runAllTests() {
|
|
305
|
+
console.log('🚀 Starting KTUI Sticky Component Tests...');
|
|
306
|
+
console.log('Testing PR #27 changes: middle, center, bottom positioning with improved offset logic\n');
|
|
307
|
+
|
|
308
|
+
this.setup();
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
await this.testMiddlePositioning();
|
|
312
|
+
await this.testCenterPositioning();
|
|
313
|
+
await this.testMiddleCenterPositioning();
|
|
314
|
+
await this.testBottomPositioning();
|
|
315
|
+
await this.testAutoPositioning();
|
|
316
|
+
await this.testExclusivePositioning();
|
|
317
|
+
await this.testLogicalProperties();
|
|
318
|
+
await this.testAutoFallbackValues();
|
|
319
|
+
|
|
320
|
+
this.printResults();
|
|
321
|
+
} catch (error) {
|
|
322
|
+
console.error('❌ Test suite failed:', error);
|
|
323
|
+
} finally {
|
|
324
|
+
this.cleanup();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Print test results
|
|
329
|
+
printResults() {
|
|
330
|
+
console.log('\n📊 Test Results Summary:');
|
|
331
|
+
console.log('='.repeat(60));
|
|
332
|
+
|
|
333
|
+
const passed = this.testResults.filter(r => r.passed).length;
|
|
334
|
+
const total = this.testResults.length;
|
|
335
|
+
|
|
336
|
+
this.testResults.forEach((result, index) => {
|
|
337
|
+
const status = result.passed ? '✅ PASS' : '❌ FAIL';
|
|
338
|
+
console.log(`${index + 1}. ${status} - ${result.test}`);
|
|
339
|
+
if (!result.passed) {
|
|
340
|
+
console.log(` Expected: ${result.expected}`);
|
|
341
|
+
console.log(` Actual: ${result.actual}`);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
console.log('='.repeat(60));
|
|
346
|
+
console.log(`Overall: ${passed}/${total} tests passed`);
|
|
347
|
+
|
|
348
|
+
if (passed === total) {
|
|
349
|
+
console.log('🎉 All tests passed! PR #27 changes are working correctly.');
|
|
350
|
+
} else {
|
|
351
|
+
console.log('⚠️ Some tests failed. Please review the implementation.');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Export for use in browser
|
|
357
|
+
if (typeof window !== 'undefined') {
|
|
358
|
+
window.StickyTestSuite = StickyTestSuite;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Auto-run tests if this file is loaded directly
|
|
362
|
+
if (typeof document !== 'undefined') {
|
|
363
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
364
|
+
const testSuite = new StickyTestSuite();
|
|
365
|
+
testSuite.runAllTests();
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export default StickyTestSuite;
|