quake2ts 0.0.553 → 0.0.557

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,6 +2,8 @@ import { Mock } from 'vitest';
2
2
  import { Vec3, CollisionPlane, CollisionBrush, CollisionNode, CollisionLeaf, CollisionModel, PlayerState, EntityState, createRandomGenerator } from '@quake2ts/shared';
3
3
  export { intersects, ladderTrace, stairTrace } from '@quake2ts/shared';
4
4
  import { GameStateSnapshot, Entity, ScriptHookRegistry, SpawnContext, EntitySystem, SpawnRegistry } from '@quake2ts/game';
5
+ import { ImageData } from '@napi-rs/canvas';
6
+ import { Browser, BrowserContext, Page } from 'playwright';
5
7
 
6
8
  interface BinaryWriterMock {
7
9
  writeByte: Mock<[number], void>;
@@ -130,6 +132,9 @@ declare function createEntity(): Entity;
130
132
  interface BrowserSetupOptions {
131
133
  url?: string;
132
134
  pretendToBeVisual?: boolean;
135
+ resources?: "usable";
136
+ enableWebGL2?: boolean;
137
+ enablePointerLock?: boolean;
133
138
  }
134
139
  /**
135
140
  * Sets up a browser environment for testing using JSDOM and napi-rs/canvas.
@@ -149,6 +154,111 @@ declare function setupNodeEnvironment(): void;
149
154
 
150
155
  declare function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext;
151
156
 
157
+ interface DrawCall {
158
+ method: string;
159
+ args: any[];
160
+ }
161
+ /**
162
+ * Creates a mock canvas element with WebGL2 support.
163
+ */
164
+ declare function createMockCanvas(width?: number, height?: number): HTMLCanvasElement;
165
+ /**
166
+ * Creates a mock 2D rendering context.
167
+ */
168
+ declare function createMockCanvasContext2D(canvas?: HTMLCanvasElement): CanvasRenderingContext2D;
169
+ /**
170
+ * Spies on draw operations for verification.
171
+ * Note: This modifies the context prototype or instance methods.
172
+ */
173
+ declare function captureCanvasDrawCalls(context: CanvasRenderingContext2D): DrawCall[];
174
+ /**
175
+ * Creates a mock ImageData object.
176
+ */
177
+ declare function createMockImageData(width: number, height: number, fillColor?: [number, number, number, number]): ImageData;
178
+ /**
179
+ * Creates a mock Image element.
180
+ */
181
+ declare function createMockImage(width?: number, height?: number, src?: string): HTMLImageElement;
182
+
183
+ interface MockRAF {
184
+ tick(timestamp?: number): void;
185
+ advance(deltaMs?: number): void;
186
+ getCallbacks(): FrameRequestCallback[];
187
+ reset(): void;
188
+ enable(): void;
189
+ disable(): void;
190
+ }
191
+ /**
192
+ * Creates a mock implementation of requestAnimationFrame that allows manual control.
193
+ * It replaces the global requestAnimationFrame and cancelAnimationFrame.
194
+ */
195
+ declare function createMockRAF(): MockRAF;
196
+ /**
197
+ * Creates a mock Performance object with controllable time.
198
+ */
199
+ declare function createMockPerformance(startTime?: number): Performance;
200
+ interface ControlledTimer {
201
+ tick(): void;
202
+ advanceBy(ms: number): void;
203
+ clear(): void;
204
+ }
205
+ /**
206
+ * Helper to simulate multiple frames of a game loop.
207
+ * @param count Number of frames to simulate
208
+ * @param frameTimeMs Time per frame in milliseconds
209
+ * @param callback Optional callback to run inside the loop (e.g. triggering inputs)
210
+ */
211
+ declare function simulateFrames(count: number, frameTimeMs?: number, callback?: (frameIndex: number) => void): void;
212
+ /**
213
+ * Simulates frames using a provided MockRAF controller.
214
+ */
215
+ declare function simulateFramesWithMock(mock: MockRAF, count: number, frameTimeMs?: number, callback?: (frameIndex: number) => void): void;
216
+
217
+ /**
218
+ * Creates a mock Storage implementation (localStorage/sessionStorage).
219
+ */
220
+ declare function createMockLocalStorage(initialData?: Record<string, string>): Storage;
221
+ /**
222
+ * Creates a mock SessionStorage implementation.
223
+ * Functionally identical to LocalStorage mock but distinct for testing isolation.
224
+ */
225
+ declare function createMockSessionStorage(initialData?: Record<string, string>): Storage;
226
+ /**
227
+ * Creates a mock IndexedDB factory.
228
+ * Currently relies on 'fake-indexeddb/auto' being imported which mocks the global indexedDB.
229
+ * This helper ensures the global is available or resets it.
230
+ */
231
+ declare function createMockIndexedDB(): IDBFactory;
232
+ interface StorageScenario {
233
+ storage: Storage;
234
+ populate(data: Record<string, string>): void;
235
+ verify(key: string, value: string): boolean;
236
+ }
237
+ /**
238
+ * Helper to setup a storage test scenario.
239
+ */
240
+ declare function createStorageTestScenario(storageType?: 'local' | 'session'): StorageScenario;
241
+
242
+ declare function createMockAudioContext(): AudioContext;
243
+ /**
244
+ * Replaces the global AudioContext with a mock.
245
+ */
246
+ declare function setupMockAudioContext(): void;
247
+ /**
248
+ * Restores the original AudioContext (if it was mocked).
249
+ */
250
+ declare function teardownMockAudioContext(): void;
251
+ interface AudioEvent {
252
+ type: string;
253
+ args: any[];
254
+ }
255
+ /**
256
+ * Captures audio operations for verification.
257
+ * Currently requires manual instrumentation or a more sophisticated Proxy mock.
258
+ * This is a placeholder for future implementation.
259
+ */
260
+ declare function captureAudioEvents(context: AudioContext): AudioEvent[];
261
+
152
262
  declare class MockPointerLock {
153
263
  static setup(doc: Document): void;
154
264
  }
@@ -164,4 +274,113 @@ declare class InputInjector {
164
274
  wheel(deltaY: number): void;
165
275
  }
166
276
 
167
- export { type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, InputInjector, type MockEngine, type MockGame, MockPointerLock, type TestContext, createBinaryStreamMock, createBinaryWriterMock, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockEngine, createMockGame, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createSpawnContext, createTestContext, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupNodeEnvironment, teardownBrowserEnvironment };
277
+ interface PlaywrightOptions {
278
+ headless?: boolean;
279
+ viewport?: {
280
+ width: number;
281
+ height: number;
282
+ };
283
+ args?: string[];
284
+ recordVideo?: {
285
+ dir: string;
286
+ size?: {
287
+ width: number;
288
+ height: number;
289
+ };
290
+ };
291
+ }
292
+ interface PlaywrightTestClient {
293
+ browser: Browser;
294
+ context: BrowserContext;
295
+ page: Page;
296
+ navigate(url: string): Promise<void>;
297
+ waitForGame(timeout?: number): Promise<void>;
298
+ injectInput(type: 'keydown' | 'keyup', key: string): Promise<void>;
299
+ injectMouse(type: 'move' | 'down' | 'up', x?: number, y?: number, button?: number): Promise<void>;
300
+ screenshot(path: string): Promise<void>;
301
+ close(): Promise<void>;
302
+ }
303
+ interface GameStateCapture {
304
+ origin?: {
305
+ x: number;
306
+ y: number;
307
+ z: number;
308
+ };
309
+ angles?: {
310
+ x: number;
311
+ y: number;
312
+ z: number;
313
+ };
314
+ health?: number;
315
+ }
316
+ /**
317
+ * Creates a Playwright test client wrapper.
318
+ */
319
+ declare function createPlaywrightTestClient(options?: PlaywrightOptions): Promise<PlaywrightTestClient>;
320
+ /**
321
+ * Waits for the game to be ready on the provided page.
322
+ */
323
+ declare function waitForGameReady(page: Page, timeout?: number): Promise<void>;
324
+ /**
325
+ * Captures the current game state from the browser.
326
+ * Requires the game to expose state globally (e.g. window.game.state).
327
+ */
328
+ declare function captureGameState(page: Page): Promise<GameStateCapture>;
329
+
330
+ interface NetworkSimulator {
331
+ apply(page: any): Promise<void>;
332
+ clear(page: any): Promise<void>;
333
+ }
334
+ type NetworkCondition = 'good' | 'slow' | 'unstable' | 'offline';
335
+ interface NetworkConfig {
336
+ offline: boolean;
337
+ downloadThroughput: number;
338
+ uploadThroughput: number;
339
+ latency: number;
340
+ }
341
+ /**
342
+ * Simulates network conditions using Chrome DevTools Protocol (CDP) via Playwright.
343
+ */
344
+ declare function simulateNetworkCondition(condition: NetworkCondition): NetworkSimulator;
345
+ /**
346
+ * Creates a custom network condition simulator.
347
+ *
348
+ * @param latency Latency in milliseconds
349
+ * @param jitter Approximate jitter (variation in latency) - Note: CDP doesn't support jitter natively, so this is just a placeholder or requires manual delay injection.
350
+ * @param packetLoss Packet loss percentage (0-100) - CDP doesn't strictly support packet loss, typically emulated via "offline" toggling or proxy. We will ignore for basic CDP emulation.
351
+ */
352
+ declare function createCustomNetworkCondition(latency: number, jitter?: number, packetLoss?: number, baseConfig?: NetworkConfig): NetworkSimulator;
353
+ /**
354
+ * Throttles bandwidth for the given page.
355
+ */
356
+ declare function throttleBandwidth(page: any, bytesPerSecond: number): Promise<void>;
357
+
358
+ interface VisualDiff {
359
+ pixelDiff: number;
360
+ diffPath?: string;
361
+ matched: boolean;
362
+ }
363
+ /**
364
+ * Captures a screenshot of the current game state.
365
+ */
366
+ declare function captureGameScreenshot(page: Page, name: string, options?: {
367
+ dir?: string;
368
+ fullPage?: boolean;
369
+ }): Promise<Buffer>;
370
+ /**
371
+ * Compares two image buffers pixel-by-pixel.
372
+ * Note: A robust implementation would use a library like 'pixelmatch' or 'looks-same'.
373
+ * For now, we provide a basic placeholder or rely on simple buffer comparison if strict equality is needed,
374
+ * but visual regression usually requires tolerance.
375
+ */
376
+ declare function compareScreenshots(baseline: Buffer, current: Buffer, threshold?: number): Promise<VisualDiff>;
377
+ interface VisualScenario {
378
+ capture(name: string): Promise<Buffer>;
379
+ compare(name: string, baselineDir: string): Promise<VisualDiff>;
380
+ }
381
+ /**
382
+ * Creates a helper for visual regression testing scenarios.
383
+ */
384
+ declare function createVisualTestScenario(page: Page, sceneName: string): VisualScenario;
385
+
386
+ export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type ControlledTimer, type DrawCall, type GameStateCapture, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type PlaywrightOptions, type PlaywrightTestClient, type StorageScenario, type TestContext, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBinaryStreamMock, createBinaryWriterMock, createCustomNetworkCondition, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockEngine, createMockGame, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockPerformance, createMockRAF, createMockSessionStorage, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createPlaywrightTestClient, createSpawnContext, createStorageTestScenario, createTestContext, createVisualTestScenario, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, simulateFrames, simulateFramesWithMock, simulateNetworkCondition, teardownBrowserEnvironment, teardownMockAudioContext, throttleBandwidth, waitForGameReady };