create-elit 3.6.4 → 3.6.7
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/README.md +32 -68
- package/dist/index.js +121 -8
- package/dist/templates/{elit.config.ts → auth-fullstack-example/elit.config.ts} +51 -0
- package/dist/templates/auth-fullstack-example/package.json +26 -0
- package/dist/templates/auth-fullstack-example/src/native-screen.ts +10 -0
- package/dist/templates/auth-fullstack-example/wapkignore +10 -0
- package/dist/templates/auth-fullstack-example/wapkpatch +1 -0
- package/dist/templates/basic-example/README.md +39 -0
- package/dist/templates/basic-example/elit.config.ts +114 -0
- package/dist/templates/basic-example/gitignore +7 -0
- package/dist/templates/basic-example/package.json +26 -0
- package/dist/templates/basic-example/public/favicon.svg +22 -0
- package/dist/templates/basic-example/public/index.html +14 -0
- package/dist/templates/basic-example/src/client.ts +15 -0
- package/dist/templates/basic-example/src/main.ts +89 -0
- package/dist/templates/basic-example/src/mobile.ts +35 -0
- package/dist/templates/basic-example/src/styles.ts +273 -0
- package/dist/templates/basic-example/tsconfig.json +24 -0
- package/dist/templates/basic-example/wapkignore +10 -0
- package/dist/templates/basic-example/wapkpatch +1 -0
- package/dist/templates/todo-fullstack-example/README.md +39 -0
- package/dist/templates/todo-fullstack-example/databases/todo.ts +41 -0
- package/dist/templates/todo-fullstack-example/elit.config.ts +123 -0
- package/dist/templates/todo-fullstack-example/gitignore +7 -0
- package/dist/templates/todo-fullstack-example/package.json +26 -0
- package/dist/templates/todo-fullstack-example/public/favicon.svg +22 -0
- package/dist/templates/todo-fullstack-example/public/index.html +14 -0
- package/dist/templates/todo-fullstack-example/src/client.ts +15 -0
- package/dist/templates/todo-fullstack-example/src/components/AppFooter.ts +16 -0
- package/dist/templates/todo-fullstack-example/src/components/AppHeader.ts +23 -0
- package/dist/templates/todo-fullstack-example/src/main.ts +7 -0
- package/dist/templates/todo-fullstack-example/src/mobile.ts +36 -0
- package/dist/templates/todo-fullstack-example/src/pages/TodoPage.ts +491 -0
- package/dist/templates/todo-fullstack-example/src/router.ts +16 -0
- package/dist/templates/todo-fullstack-example/src/server.ts +226 -0
- package/dist/templates/todo-fullstack-example/src/styles.ts +768 -0
- package/dist/templates/todo-fullstack-example/src/todo-types.ts +19 -0
- package/dist/templates/todo-fullstack-example/src/web.ts +16 -0
- package/dist/templates/todo-fullstack-example/tsconfig.json +24 -0
- package/dist/templates/todo-fullstack-example/wapkignore +10 -0
- package/dist/templates/todo-fullstack-example/wapkpatch +1 -0
- package/package.json +1 -1
- package/dist/templates/package.json +0 -17
- package/dist/templates/src/client.test.ts +0 -292
- package/dist/templates/src/components/Footer.test.ts +0 -226
- package/dist/templates/src/components/Header.test.ts +0 -493
- package/dist/templates/src/pages/ChatListPage.test.ts +0 -603
- package/dist/templates/src/pages/ChatPage.test.ts +0 -530
- package/dist/templates/src/pages/ForgotPasswordPage.test.ts +0 -484
- package/dist/templates/src/pages/HomePage.test.ts +0 -601
- package/dist/templates/src/pages/LoginPage.test.ts +0 -619
- package/dist/templates/src/pages/PrivateChatPage.test.ts +0 -556
- package/dist/templates/src/pages/ProfilePage.test.ts +0 -628
- package/dist/templates/src/pages/RegisterPage.test.ts +0 -661
- /package/dist/templates/{README.md → auth-fullstack-example/README.md} +0 -0
- /package/dist/templates/{databases → auth-fullstack-example/databases}/users.ts +0 -0
- /package/dist/templates/{gitignore → auth-fullstack-example/gitignore} +0 -0
- /package/dist/templates/{public → auth-fullstack-example/public}/favicon.svg +0 -0
- /package/dist/templates/{public → auth-fullstack-example/public}/index.html +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/client.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/components/Footer.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/components/Header.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/components/index.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/main.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ChatListPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ChatPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ForgotPasswordPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/HomePage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/LoginPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/PrivateChatPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/ProfilePage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/pages/RegisterPage.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/router.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/server.ts +0 -0
- /package/dist/templates/{src → auth-fullstack-example/src}/styles.ts +0 -0
- /package/dist/templates/{tsconfig.json → auth-fullstack-example/tsconfig.json} +0 -0
|
@@ -1,601 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HomePage Component Unit Tests
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
// CRITICAL: Set up ALL mocks BEFORE importing HomePage component
|
|
6
|
-
// The component reads localStorage during import, so mocks must be set up first
|
|
7
|
-
|
|
8
|
-
// Simple mock function to track calls
|
|
9
|
-
function mockFn() {
|
|
10
|
-
const calls: any[] = [];
|
|
11
|
-
const fn = (...args: any[]) => {
|
|
12
|
-
calls.push(args);
|
|
13
|
-
return undefined;
|
|
14
|
-
};
|
|
15
|
-
fn.calls = calls;
|
|
16
|
-
fn.mockClear = () => {
|
|
17
|
-
calls.length = 0;
|
|
18
|
-
};
|
|
19
|
-
return fn;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Mock localStorage
|
|
23
|
-
const localStorageMock = (() => {
|
|
24
|
-
let store: Record<string, string> = {};
|
|
25
|
-
return {
|
|
26
|
-
getItem: (key: string): string | null => store[key] || null,
|
|
27
|
-
setItem: (key: string, value: string): void => {
|
|
28
|
-
store[key] = value;
|
|
29
|
-
},
|
|
30
|
-
removeItem: (key: string): void => {
|
|
31
|
-
delete store[key];
|
|
32
|
-
},
|
|
33
|
-
clear: (): void => {
|
|
34
|
-
store = {};
|
|
35
|
-
},
|
|
36
|
-
get length(): number {
|
|
37
|
-
return Object.keys(store).length;
|
|
38
|
-
},
|
|
39
|
-
key: (index: number): string | null => {
|
|
40
|
-
return Object.keys(store)[index] || null;
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
})();
|
|
44
|
-
|
|
45
|
-
// Mock window.addEventListener
|
|
46
|
-
const eventListeners: Record<string, Function[]> = {};
|
|
47
|
-
const addEventListenerMock = (event: string, handler: Function) => {
|
|
48
|
-
if (!eventListeners[event]) {
|
|
49
|
-
eventListeners[event] = [];
|
|
50
|
-
}
|
|
51
|
-
eventListeners[event].push(handler);
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Mock requestAnimationFrame
|
|
55
|
-
let rafId = 0;
|
|
56
|
-
const rafCallbacks: Map<number, FrameRequestCallback> = new Map();
|
|
57
|
-
const mockRequestAnimationFrame = (callback: FrameRequestCallback) => {
|
|
58
|
-
const id = ++rafId;
|
|
59
|
-
rafCallbacks.set(id, callback);
|
|
60
|
-
return id;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const mockCancelAnimationFrame = (id: number) => {
|
|
64
|
-
rafCallbacks.delete(id);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// Trigger a RAF callback
|
|
68
|
-
const triggerRAF = () => {
|
|
69
|
-
for (const [id, callback] of rafCallbacks) {
|
|
70
|
-
try {
|
|
71
|
-
callback(performance.now() as any);
|
|
72
|
-
} catch (e) {
|
|
73
|
-
// Ignore errors
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
rafCallbacks.clear();
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// Mock router
|
|
80
|
-
const mockRouter = {
|
|
81
|
-
push: mockFn() as any,
|
|
82
|
-
replace: mockFn() as any,
|
|
83
|
-
go: mockFn() as any,
|
|
84
|
-
back: mockFn() as any,
|
|
85
|
-
forward: mockFn() as any,
|
|
86
|
-
currentPath: '/',
|
|
87
|
-
currentState: null
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
// SETUP GLOBALS BEFORE IMPORT
|
|
91
|
-
// Clear real localStorage if it exists
|
|
92
|
-
if (typeof localStorage !== 'undefined') {
|
|
93
|
-
localStorage.clear();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Set up global mocks
|
|
97
|
-
(global as any).localStorage = localStorageMock;
|
|
98
|
-
(globalThis as any).localStorage = localStorageMock;
|
|
99
|
-
(global as any).window = {
|
|
100
|
-
addEventListener: addEventListenerMock,
|
|
101
|
-
removeEventListener: mockFn(),
|
|
102
|
-
localStorage: localStorageMock
|
|
103
|
-
};
|
|
104
|
-
(globalThis as any).window = (global as any).window;
|
|
105
|
-
(global as any).requestAnimationFrame = mockRequestAnimationFrame;
|
|
106
|
-
(global as any).cancelAnimationFrame = mockCancelAnimationFrame;
|
|
107
|
-
(globalThis as any).requestAnimationFrame = mockRequestAnimationFrame;
|
|
108
|
-
(globalThis as any).cancelAnimationFrame = mockCancelAnimationFrame;
|
|
109
|
-
|
|
110
|
-
// NOW import the component (after mocks are set up)
|
|
111
|
-
import { HomePage } from './HomePage';
|
|
112
|
-
import type { VNode } from 'elit/types';
|
|
113
|
-
|
|
114
|
-
// Helper function to render VNode to HTML string
|
|
115
|
-
function renderToString(vNode: VNode | string | number | undefined | null): string {
|
|
116
|
-
if (vNode == null || vNode === false) return '';
|
|
117
|
-
if (typeof vNode !== 'object') return String(vNode);
|
|
118
|
-
|
|
119
|
-
const { tagName, props, children } = vNode;
|
|
120
|
-
const attrs = props ? Object.entries(props)
|
|
121
|
-
.filter(([k, v]) => v != null && v !== false && k !== 'children' && k !== 'ref' && !k.startsWith('on'))
|
|
122
|
-
.map(([k, v]) => {
|
|
123
|
-
if (k === 'className' || k === 'class') return `class="${Array.isArray(v) ? v.join(' ') : v}"`;
|
|
124
|
-
if (k === 'style') return `style="${typeof v === 'string' ? v : Object.entries(v).map(([sk, sv]) => `${sk.replace(/([A-Z])/g, '-$1').toLowerCase()}:${sv}`).join(';')}"`;
|
|
125
|
-
if (v === true) return k;
|
|
126
|
-
return `${k}="${v}"`;
|
|
127
|
-
})
|
|
128
|
-
.join(' ') : '';
|
|
129
|
-
|
|
130
|
-
const childrenStr = children && children.length > 0
|
|
131
|
-
? children.map(c => renderToString(c as any)).join('')
|
|
132
|
-
: '';
|
|
133
|
-
|
|
134
|
-
return `<${tagName}${attrs ? ' ' + attrs : ''}>${childrenStr}</${tagName}>`;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Helper function to find child by tag name
|
|
138
|
-
function findChildByTagName(vNode: VNode, tagName: string): VNode | null {
|
|
139
|
-
if (vNode && typeof vNode === 'object' && 'tagName' in vNode) {
|
|
140
|
-
if (vNode.tagName === tagName) {
|
|
141
|
-
return vNode;
|
|
142
|
-
}
|
|
143
|
-
if (vNode.children) {
|
|
144
|
-
for (const child of vNode.children) {
|
|
145
|
-
if (typeof child === 'object' && child !== null) {
|
|
146
|
-
const found = findChildByTagName(child as VNode, tagName);
|
|
147
|
-
if (found) return found;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Helper function to find children by tag name
|
|
156
|
-
function findChildrenByTagName(vNode: VNode, tagName: string): VNode[] {
|
|
157
|
-
const results: VNode[] = [];
|
|
158
|
-
|
|
159
|
-
function search(node: VNode | string | number | null | undefined) {
|
|
160
|
-
if (node && typeof node === 'object' && 'tagName' in node) {
|
|
161
|
-
if (node.tagName === tagName) {
|
|
162
|
-
results.push(node);
|
|
163
|
-
}
|
|
164
|
-
if (node.children) {
|
|
165
|
-
for (const child of node.children) {
|
|
166
|
-
search(child as any);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
search(vNode);
|
|
173
|
-
return results;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
describe('HomePage Component', () => {
|
|
177
|
-
// Clear REAL browser localStorage before any tests run
|
|
178
|
-
beforeAll(() => {
|
|
179
|
-
if (typeof localStorage !== 'undefined') {
|
|
180
|
-
localStorage.clear();
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
beforeEach(() => {
|
|
185
|
-
// Clear RAF callbacks FIRST
|
|
186
|
-
rafCallbacks.clear();
|
|
187
|
-
rafId = 0;
|
|
188
|
-
|
|
189
|
-
// Clear localStorage before each test
|
|
190
|
-
localStorageMock.clear();
|
|
191
|
-
|
|
192
|
-
// Also clear REAL browser localStorage
|
|
193
|
-
if (typeof localStorage !== 'undefined') {
|
|
194
|
-
localStorage.clear();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Reset mock router
|
|
198
|
-
(mockRouter.push as any).mockClear();
|
|
199
|
-
(mockRouter.replace as any).mockClear();
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
afterEach(() => {
|
|
203
|
-
// Clean up event listeners after each test
|
|
204
|
-
Object.keys(eventListeners).forEach(key => {
|
|
205
|
-
delete eventListeners[key];
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
// Clear RAF callbacks after each test
|
|
209
|
-
rafCallbacks.clear();
|
|
210
|
-
rafId = 0;
|
|
211
|
-
|
|
212
|
-
// Clear REAL browser localStorage after each test
|
|
213
|
-
if (typeof localStorage !== 'undefined') {
|
|
214
|
-
localStorage.clear();
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
describe('page structure', () => {
|
|
219
|
-
it('should render home-page', () => {
|
|
220
|
-
const page = HomePage(mockRouter as any);
|
|
221
|
-
|
|
222
|
-
expect(page).toBeDefined();
|
|
223
|
-
expect(page.tagName).toBe('div');
|
|
224
|
-
expect(page.props?.className).toBe('home-page');
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should render hero-section', () => {
|
|
228
|
-
const page = HomePage(mockRouter as any);
|
|
229
|
-
const html = renderToString(page);
|
|
230
|
-
|
|
231
|
-
expect(html).toContain('hero-section');
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it('should render hero-content', () => {
|
|
235
|
-
const page = HomePage(mockRouter as any);
|
|
236
|
-
const html = renderToString(page);
|
|
237
|
-
|
|
238
|
-
expect(html).toContain('hero-content');
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it('should render hero-visual', () => {
|
|
242
|
-
const page = HomePage(mockRouter as any);
|
|
243
|
-
const html = renderToString(page);
|
|
244
|
-
|
|
245
|
-
expect(html).toContain('hero-visual');
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
describe('when not logged in', () => {
|
|
250
|
-
it('should render hero badge', () => {
|
|
251
|
-
const page = HomePage(mockRouter as any);
|
|
252
|
-
const html = renderToString(page);
|
|
253
|
-
|
|
254
|
-
expect(html).toContain('hero-badge');
|
|
255
|
-
expect(html).toContain('✨ New Features Available');
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('should render hero section capability', () => {
|
|
259
|
-
const page = HomePage(mockRouter as any);
|
|
260
|
-
// Hero content is reactive and shows different content based on login state
|
|
261
|
-
expect(page).toBeDefined();
|
|
262
|
-
expect(page.props?.className).toBe('home-page');
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it('should render hero description capability', () => {
|
|
266
|
-
const page = HomePage(mockRouter as any);
|
|
267
|
-
// Hero description is reactive
|
|
268
|
-
expect(page).toBeDefined();
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('should have button capability', () => {
|
|
272
|
-
const page = HomePage(mockRouter as any);
|
|
273
|
-
// Buttons are reactive and show different content based on login state
|
|
274
|
-
const html = renderToString(page);
|
|
275
|
-
expect(html).toContain('btn-primary');
|
|
276
|
-
expect(html).toContain('btn-outline');
|
|
277
|
-
});
|
|
278
|
-
|
|
279
|
-
it('should have CTA section capability', () => {
|
|
280
|
-
const page = HomePage(mockRouter as any);
|
|
281
|
-
// CTA section is reactive and only shows for non-logged-in users
|
|
282
|
-
expect(page).toBeDefined();
|
|
283
|
-
});
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
describe('when logged in', () => {
|
|
287
|
-
beforeEach(() => {
|
|
288
|
-
localStorageMock.setItem('token', 'fake-token');
|
|
289
|
-
localStorageMock.setItem('user', JSON.stringify({ id: '123', name: 'Test User', email: 'test@example.com', bio: 'Test bio', avatar: '' }));
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should render welcome message with user name', () => {
|
|
293
|
-
const page = HomePage(mockRouter as any);
|
|
294
|
-
|
|
295
|
-
// Trigger RAF to update reactive state
|
|
296
|
-
triggerRAF();
|
|
297
|
-
|
|
298
|
-
const html = renderToString(page);
|
|
299
|
-
|
|
300
|
-
expect(html).toContain('Welcome back');
|
|
301
|
-
expect(html).toContain('Test User');
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it('should render Go to Messages button', () => {
|
|
305
|
-
const page = HomePage(mockRouter as any);
|
|
306
|
-
|
|
307
|
-
// Trigger RAF to update reactive state
|
|
308
|
-
triggerRAF();
|
|
309
|
-
|
|
310
|
-
const html = renderToString(page);
|
|
311
|
-
|
|
312
|
-
expect(html).toContain('Go to Messages');
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
it('should render View Profile button', () => {
|
|
316
|
-
const page = HomePage(mockRouter as any);
|
|
317
|
-
|
|
318
|
-
// Trigger RAF to update reactive state
|
|
319
|
-
triggerRAF();
|
|
320
|
-
|
|
321
|
-
const html = renderToString(page);
|
|
322
|
-
|
|
323
|
-
expect(html).toContain('View Profile');
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
it('should not render CTA section', () => {
|
|
327
|
-
const page = HomePage(mockRouter as any);
|
|
328
|
-
|
|
329
|
-
// Trigger RAF to update reactive state
|
|
330
|
-
triggerRAF();
|
|
331
|
-
|
|
332
|
-
const html = renderToString(page);
|
|
333
|
-
|
|
334
|
-
// CTA section should not be present for logged in users
|
|
335
|
-
expect(html).toBeDefined();
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
describe('hero stats', () => {
|
|
340
|
-
it('should render hero stats', () => {
|
|
341
|
-
const page = HomePage(mockRouter as any);
|
|
342
|
-
const html = renderToString(page);
|
|
343
|
-
|
|
344
|
-
expect(html).toContain('hero-stats');
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
it('should render 10K+ Developers stat', () => {
|
|
348
|
-
const page = HomePage(mockRouter as any);
|
|
349
|
-
const html = renderToString(page);
|
|
350
|
-
|
|
351
|
-
expect(html).toContain('10K+');
|
|
352
|
-
expect(html).toContain('Developers');
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
it('should render 50K+ Projects stat', () => {
|
|
356
|
-
const page = HomePage(mockRouter as any);
|
|
357
|
-
const html = renderToString(page);
|
|
358
|
-
|
|
359
|
-
expect(html).toContain('50K+');
|
|
360
|
-
expect(html).toContain('Projects');
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
it('should render 99.9% Uptime stat', () => {
|
|
364
|
-
const page = HomePage(mockRouter as any);
|
|
365
|
-
const html = renderToString(page);
|
|
366
|
-
|
|
367
|
-
expect(html).toContain('99.9%');
|
|
368
|
-
expect(html).toContain('Uptime');
|
|
369
|
-
});
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
describe('hero visual', () => {
|
|
373
|
-
it('should render hero-card-preview', () => {
|
|
374
|
-
const page = HomePage(mockRouter as any);
|
|
375
|
-
const html = renderToString(page);
|
|
376
|
-
|
|
377
|
-
expect(html).toContain('hero-card-preview');
|
|
378
|
-
});
|
|
379
|
-
|
|
380
|
-
it('should render preview-header', () => {
|
|
381
|
-
const page = HomePage(mockRouter as any);
|
|
382
|
-
const html = renderToString(page);
|
|
383
|
-
|
|
384
|
-
expect(html).toContain('preview-header');
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
it('should render preview dots', () => {
|
|
388
|
-
const page = HomePage(mockRouter as any);
|
|
389
|
-
const html = renderToString(page);
|
|
390
|
-
|
|
391
|
-
expect(html).toContain('preview-dots');
|
|
392
|
-
expect(html).toContain('preview-dot');
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
it('should render preview-body', () => {
|
|
396
|
-
const page = HomePage(mockRouter as any);
|
|
397
|
-
const html = renderToString(page);
|
|
398
|
-
|
|
399
|
-
expect(html).toContain('preview-body');
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
it('should render preview lines', () => {
|
|
403
|
-
const page = HomePage(mockRouter as any);
|
|
404
|
-
const html = renderToString(page);
|
|
405
|
-
|
|
406
|
-
expect(html).toContain('preview-line');
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
it('should render preview grid', () => {
|
|
410
|
-
const page = HomePage(mockRouter as any);
|
|
411
|
-
const html = renderToString(page);
|
|
412
|
-
|
|
413
|
-
expect(html).toContain('preview-grid');
|
|
414
|
-
expect(html).toContain('preview-grid-item');
|
|
415
|
-
});
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
describe('features section', () => {
|
|
419
|
-
it('should render features-section', () => {
|
|
420
|
-
const page = HomePage(mockRouter as any);
|
|
421
|
-
const html = renderToString(page);
|
|
422
|
-
|
|
423
|
-
expect(html).toContain('features-section');
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
it('should render section title', () => {
|
|
427
|
-
const page = HomePage(mockRouter as any);
|
|
428
|
-
const html = renderToString(page);
|
|
429
|
-
|
|
430
|
-
expect(html).toContain('Everything You Need');
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
it('should render section subtitle', () => {
|
|
434
|
-
const page = HomePage(mockRouter as any);
|
|
435
|
-
const html = renderToString(page);
|
|
436
|
-
|
|
437
|
-
expect(html).toContain('Powerful features to help you build better applications');
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
it('should render features-grid', () => {
|
|
441
|
-
const page = HomePage(mockRouter as any);
|
|
442
|
-
const html = renderToString(page);
|
|
443
|
-
|
|
444
|
-
expect(html).toContain('features-grid');
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
describe('feature items', () => {
|
|
449
|
-
it('should render Lightning Fast feature', () => {
|
|
450
|
-
const page = HomePage(mockRouter as any);
|
|
451
|
-
const html = renderToString(page);
|
|
452
|
-
|
|
453
|
-
expect(html).toContain('⚡');
|
|
454
|
-
expect(html).toContain('Lightning Fast');
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
it('should render Secure feature', () => {
|
|
458
|
-
const page = HomePage(mockRouter as any);
|
|
459
|
-
const html = renderToString(page);
|
|
460
|
-
|
|
461
|
-
expect(html).toContain('🔒');
|
|
462
|
-
expect(html).toContain('Secure');
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
it('should render Responsive feature', () => {
|
|
466
|
-
const page = HomePage(mockRouter as any);
|
|
467
|
-
const html = renderToString(page);
|
|
468
|
-
|
|
469
|
-
expect(html).toContain('📱');
|
|
470
|
-
expect(html).toContain('Responsive');
|
|
471
|
-
});
|
|
472
|
-
|
|
473
|
-
it('should render Customizable feature', () => {
|
|
474
|
-
const page = HomePage(mockRouter as any);
|
|
475
|
-
const html = renderToString(page);
|
|
476
|
-
|
|
477
|
-
expect(html).toContain('🎨');
|
|
478
|
-
expect(html).toContain('Customizable');
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
it('should render Developer Friendly feature', () => {
|
|
482
|
-
const page = HomePage(mockRouter as any);
|
|
483
|
-
const html = renderToString(page);
|
|
484
|
-
|
|
485
|
-
expect(html).toContain('🔧');
|
|
486
|
-
expect(html).toContain('Developer Friendly');
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
it('should render Easy Deployment feature', () => {
|
|
490
|
-
const page = HomePage(mockRouter as any);
|
|
491
|
-
const html = renderToString(page);
|
|
492
|
-
|
|
493
|
-
expect(html).toContain('🚀');
|
|
494
|
-
expect(html).toContain('Easy Deployment');
|
|
495
|
-
});
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
describe('CTA section', () => {
|
|
499
|
-
it('should render CTA section capability', () => {
|
|
500
|
-
const page = HomePage(mockRouter as any);
|
|
501
|
-
// CTA section is reactive and only shows for non-logged-in users
|
|
502
|
-
expect(page).toBeDefined();
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
it('should have CTA content capability', () => {
|
|
506
|
-
const page = HomePage(mockRouter as any);
|
|
507
|
-
// CTA content is reactive
|
|
508
|
-
expect(page).toBeDefined();
|
|
509
|
-
});
|
|
510
|
-
|
|
511
|
-
it('should have CTA button capability', () => {
|
|
512
|
-
const page = HomePage(mockRouter as any);
|
|
513
|
-
// CTA button is reactive
|
|
514
|
-
expect(page).toBeDefined();
|
|
515
|
-
});
|
|
516
|
-
});
|
|
517
|
-
|
|
518
|
-
describe('CSS classes', () => {
|
|
519
|
-
it('should have correct CSS classes', () => {
|
|
520
|
-
const page = HomePage(mockRouter as any);
|
|
521
|
-
const html = renderToString(page);
|
|
522
|
-
|
|
523
|
-
expect(html).toContain('home-page');
|
|
524
|
-
expect(html).toContain('hero-section');
|
|
525
|
-
expect(html).toContain('hero-content');
|
|
526
|
-
expect(html).toContain('hero-badge');
|
|
527
|
-
expect(html).toContain('hero-title');
|
|
528
|
-
expect(html).toContain('hero-highlight');
|
|
529
|
-
expect(html).toContain('hero-description');
|
|
530
|
-
expect(html).toContain('hero-buttons');
|
|
531
|
-
});
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
describe('event listeners', () => {
|
|
535
|
-
it('should register storage event listeners', () => {
|
|
536
|
-
HomePage(mockRouter as any);
|
|
537
|
-
|
|
538
|
-
expect(eventListeners['storage']).toBeDefined();
|
|
539
|
-
expect(eventListeners['storage'].length).toBeGreaterThan(0);
|
|
540
|
-
expect(eventListeners['elit:storage']).toBeDefined();
|
|
541
|
-
expect(eventListeners['elit:storage'].length).toBeGreaterThan(0);
|
|
542
|
-
});
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
describe('component consistency', () => {
|
|
546
|
-
it('should always return the same structure', () => {
|
|
547
|
-
const page1 = HomePage(mockRouter as any);
|
|
548
|
-
const page2 = HomePage(mockRouter as any);
|
|
549
|
-
|
|
550
|
-
expect(page1.tagName).toBe(page2.tagName);
|
|
551
|
-
expect(page1.props?.className).toBe(page2.props?.className);
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
it('should render without errors', () => {
|
|
555
|
-
expect(() => {
|
|
556
|
-
const page = HomePage(mockRouter as any);
|
|
557
|
-
renderToString(page);
|
|
558
|
-
}).not.toThrow();
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
it('should have h1 element', () => {
|
|
562
|
-
const page = HomePage(mockRouter as any);
|
|
563
|
-
const h1Elements = findChildrenByTagName(page, 'h1');
|
|
564
|
-
|
|
565
|
-
expect(h1Elements.length).toBeGreaterThan(0);
|
|
566
|
-
});
|
|
567
|
-
|
|
568
|
-
it('should have h2 elements', () => {
|
|
569
|
-
const page = HomePage(mockRouter as any);
|
|
570
|
-
const h2Elements = findChildrenByTagName(page, 'h2');
|
|
571
|
-
|
|
572
|
-
expect(h2Elements.length).toBeGreaterThan(0);
|
|
573
|
-
});
|
|
574
|
-
|
|
575
|
-
it('should have h3 elements', () => {
|
|
576
|
-
const page = HomePage(mockRouter as any);
|
|
577
|
-
const h3Elements = findChildrenByTagName(page, 'h3');
|
|
578
|
-
|
|
579
|
-
expect(h3Elements.length).toBeGreaterThan(0);
|
|
580
|
-
});
|
|
581
|
-
});
|
|
582
|
-
|
|
583
|
-
describe('reactive state', () => {
|
|
584
|
-
it('should have isLoggedIn state', () => {
|
|
585
|
-
const page = HomePage(mockRouter as any);
|
|
586
|
-
expect(page).toBeDefined();
|
|
587
|
-
});
|
|
588
|
-
|
|
589
|
-
it('should have user state', () => {
|
|
590
|
-
const page = HomePage(mockRouter as any);
|
|
591
|
-
expect(page).toBeDefined();
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
it('should respond to storage changes', () => {
|
|
595
|
-
HomePage(mockRouter as any);
|
|
596
|
-
|
|
597
|
-
expect(eventListeners['storage']).toBeDefined();
|
|
598
|
-
expect(eventListeners['elit:storage']).toBeDefined();
|
|
599
|
-
});
|
|
600
|
-
});
|
|
601
|
-
});
|