quake2ts 0.0.562 → 0.0.563

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.
@@ -310,11 +310,14 @@ declare function createMockImageData(width: number, height: number, fillColor?:
310
310
  */
311
311
  declare function createMockImage(width?: number, height?: number, src?: string): HTMLImageElement;
312
312
 
313
+ interface NodeSetupOptions {
314
+ polyfillFetch?: boolean;
315
+ }
313
316
  /**
314
317
  * Sets up a Node.js environment for testing.
315
318
  * This is primarily for backend or shared logic that doesn't rely on browser APIs.
316
319
  */
317
- declare function setupNodeEnvironment(): void;
320
+ declare function setupNodeEnvironment(options?: NodeSetupOptions): void;
318
321
 
319
322
  declare function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext;
320
323
 
@@ -334,14 +337,14 @@ declare function createMockSessionStorage(initialData?: Record<string, string>):
334
337
  */
335
338
  declare function createMockIndexedDB(): IDBFactory;
336
339
  interface StorageScenario {
337
- storage: Storage;
338
- populate(data: Record<string, string>): void;
339
- verify(key: string, value: string): boolean;
340
+ storage: Storage | IDBFactory;
341
+ populate(data: Record<string, any>): Promise<void> | void;
342
+ verify(key: string, value: any): Promise<boolean> | boolean;
340
343
  }
341
344
  /**
342
345
  * Helper to setup a storage test scenario.
343
346
  */
344
- declare function createStorageTestScenario(storageType?: 'local' | 'session'): StorageScenario;
347
+ declare function createStorageTestScenario(storageType?: 'local' | 'session' | 'indexed'): StorageScenario;
345
348
 
346
349
  declare function createMockAudioContext(): AudioContext;
347
350
  /**
@@ -358,8 +361,7 @@ interface AudioEvent {
358
361
  }
359
362
  /**
360
363
  * Captures audio operations for verification.
361
- * Currently requires manual instrumentation or a more sophisticated Proxy mock.
362
- * This is a placeholder for future implementation.
364
+ * Note: Only works if the context was created via createMockAudioContext which proxies calls.
363
365
  */
364
366
  declare function captureAudioEvents(context: AudioContext): AudioEvent[];
365
367
 
@@ -452,4 +454,59 @@ declare class InputInjector {
452
454
  wheel(deltaY: number): void;
453
455
  }
454
456
 
455
- export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type ControlledTimer, type DrawCall, type GameState, type GameStateCapture, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type MockServer, MockTransport, type MockUDPSocket, type NetworkAddress, type PlaywrightOptions, type PlaywrightTestClient, type StorageScenario, type TestContext, captureAudioEvents, captureCanvasDrawCalls, captureGameState, createBinaryStreamMock, createBinaryWriterMock, createControlledTimer, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockEngine, createMockGame, createMockGameState, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockNetworkAddress, createMockPerformance, createMockRAF, createMockServer, createMockServerClient, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createPlaywrightTestClient, createSpawnContext, createStorageTestScenario, createTestContext, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupMockAudioContext, setupNodeEnvironment, simulateFrames, simulateFramesWithMock, teardownBrowserEnvironment, teardownMockAudioContext, waitForGameReady };
457
+ interface NetworkSimulator {
458
+ apply(page: any): Promise<void>;
459
+ clear(page: any): Promise<void>;
460
+ }
461
+ type NetworkCondition = 'good' | 'slow' | 'unstable' | 'offline';
462
+ interface NetworkConfig {
463
+ offline: boolean;
464
+ downloadThroughput: number;
465
+ uploadThroughput: number;
466
+ latency: number;
467
+ }
468
+ /**
469
+ * Simulates network conditions using Chrome DevTools Protocol (CDP) via Playwright.
470
+ */
471
+ declare function simulateNetworkCondition(condition: NetworkCondition): NetworkSimulator;
472
+ /**
473
+ * Creates a custom network condition simulator.
474
+ *
475
+ * @param latency Latency in milliseconds
476
+ * @param jitter Approximate jitter (variation in latency) - Note: CDP doesn't support jitter natively.
477
+ * @param packetLoss Packet loss percentage (0-100) - Ignored for basic CDP emulation.
478
+ */
479
+ declare function createCustomNetworkCondition(latency: number, jitter?: number, packetLoss?: number, baseConfig?: NetworkConfig): NetworkSimulator;
480
+ /**
481
+ * Throttles bandwidth for the given page.
482
+ */
483
+ declare function throttleBandwidth(page: any, bytesPerSecond: number): Promise<void>;
484
+
485
+ interface VisualDiff {
486
+ pixelDiff: number;
487
+ diffPath?: string;
488
+ matched: boolean;
489
+ }
490
+ /**
491
+ * Captures a screenshot of the current game state.
492
+ */
493
+ declare function captureGameScreenshot(page: Page, name: string, options?: {
494
+ dir?: string;
495
+ fullPage?: boolean;
496
+ }): Promise<Buffer>;
497
+ /**
498
+ * Compares two image buffers pixel-by-pixel.
499
+ * Note: A robust implementation would use a library like 'pixelmatch' or 'looks-same'.
500
+ * For now, we provide a basic placeholder or rely on simple buffer comparison.
501
+ */
502
+ declare function compareScreenshots(baseline: Buffer, current: Buffer, threshold?: number): Promise<VisualDiff>;
503
+ interface VisualScenario {
504
+ capture(name: string): Promise<Buffer>;
505
+ compare(name: string, baselineDir: string): Promise<VisualDiff>;
506
+ }
507
+ /**
508
+ * Creates a helper for visual regression testing scenarios.
509
+ */
510
+ declare function createVisualTestScenario(page: Page, sceneName: string): VisualScenario;
511
+
512
+ export { type AudioEvent, type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, type ControlledTimer, type DrawCall, type GameState, type GameStateCapture, InputInjector, type MockEngine, type MockGame, MockPointerLock, type MockRAF, type MockServer, MockTransport, type MockUDPSocket, type NetworkAddress, type NetworkCondition, type NetworkConfig, type NetworkSimulator, type NodeSetupOptions, type PlaywrightOptions, type PlaywrightTestClient, type StorageScenario, type TestContext, type VisualDiff, type VisualScenario, captureAudioEvents, captureCanvasDrawCalls, captureGameScreenshot, captureGameState, compareScreenshots, createBinaryStreamMock, createBinaryWriterMock, createControlledTimer, createCustomNetworkCondition, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockAudioContext, createMockCanvas, createMockCanvasContext2D, createMockEngine, createMockGame, createMockGameState, createMockImage, createMockImageData, createMockIndexedDB, createMockLocalStorage, createMockNetworkAddress, createMockPerformance, createMockRAF, createMockServer, createMockServerClient, createMockServerState, createMockServerStatic, createMockSessionStorage, createMockTransport, createMockUDPSocket, 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 };
@@ -1080,8 +1080,8 @@ function createMockImage(width, height, src) {
1080
1080
  }
1081
1081
 
1082
1082
  // src/setup/node.ts
1083
- function setupNodeEnvironment() {
1084
- if (typeof global.fetch === "undefined") {
1083
+ function setupNodeEnvironment(options = {}) {
1084
+ if (options.polyfillFetch && typeof global.fetch === "undefined") {
1085
1085
  }
1086
1086
  }
1087
1087
 
@@ -1110,6 +1110,61 @@ function createMockIndexedDB() {
1110
1110
  return indexedDB;
1111
1111
  }
1112
1112
  function createStorageTestScenario(storageType = "local") {
1113
+ if (storageType === "indexed") {
1114
+ const dbName = `test-db-${Math.random().toString(36).substring(7)}`;
1115
+ const storeName = "test-store";
1116
+ const storage2 = createMockIndexedDB();
1117
+ return {
1118
+ storage: storage2,
1119
+ populate: async (data) => {
1120
+ return new Promise((resolve, reject) => {
1121
+ const req = storage2.open(dbName, 1);
1122
+ req.onupgradeneeded = (e) => {
1123
+ const db = e.target.result;
1124
+ db.createObjectStore(storeName);
1125
+ };
1126
+ req.onsuccess = (e) => {
1127
+ const db = e.target.result;
1128
+ const tx = db.transaction(storeName, "readwrite");
1129
+ const store = tx.objectStore(storeName);
1130
+ Object.entries(data).forEach(([k, v]) => store.put(v, k));
1131
+ tx.oncomplete = () => {
1132
+ db.close();
1133
+ resolve();
1134
+ };
1135
+ tx.onerror = () => reject(tx.error);
1136
+ };
1137
+ req.onerror = () => reject(req.error);
1138
+ });
1139
+ },
1140
+ verify: async (key, value) => {
1141
+ return new Promise((resolve, reject) => {
1142
+ const req = storage2.open(dbName, 1);
1143
+ req.onsuccess = (e) => {
1144
+ const db = e.target.result;
1145
+ if (!db.objectStoreNames.contains(storeName)) {
1146
+ db.close();
1147
+ resolve(false);
1148
+ return;
1149
+ }
1150
+ const tx = db.transaction(storeName, "readonly");
1151
+ const store = tx.objectStore(storeName);
1152
+ const getReq = store.get(key);
1153
+ getReq.onsuccess = () => {
1154
+ const result = getReq.result === value;
1155
+ db.close();
1156
+ resolve(result);
1157
+ };
1158
+ getReq.onerror = () => {
1159
+ db.close();
1160
+ resolve(false);
1161
+ };
1162
+ };
1163
+ req.onerror = () => reject(req.error);
1164
+ });
1165
+ }
1166
+ };
1167
+ }
1113
1168
  const storage = storageType === "local" ? createMockLocalStorage() : createMockSessionStorage();
1114
1169
  return {
1115
1170
  storage,
@@ -1124,7 +1179,7 @@ function createStorageTestScenario(storageType = "local") {
1124
1179
 
1125
1180
  // src/setup/audio.ts
1126
1181
  function createMockAudioContext() {
1127
- return {
1182
+ const context = {
1128
1183
  createGain: () => ({
1129
1184
  connect: () => {
1130
1185
  },
@@ -1173,8 +1228,23 @@ function createMockAudioContext() {
1173
1228
  sampleRate,
1174
1229
  numberOfChannels: channels,
1175
1230
  getChannelData: () => new Float32Array(length)
1176
- })
1231
+ }),
1232
+ // Helper to track events if needed
1233
+ _events: []
1177
1234
  };
1235
+ return new Proxy(context, {
1236
+ get(target, prop, receiver) {
1237
+ if (prop === "_events") return target._events;
1238
+ const value = Reflect.get(target, prop, receiver);
1239
+ if (typeof value === "function") {
1240
+ return (...args) => {
1241
+ target._events.push({ type: String(prop), args });
1242
+ return Reflect.apply(value, target, args);
1243
+ };
1244
+ }
1245
+ return value;
1246
+ }
1247
+ });
1178
1248
  }
1179
1249
  function setupMockAudioContext() {
1180
1250
  if (typeof global.AudioContext === "undefined" && typeof global.window !== "undefined") {
@@ -1195,7 +1265,7 @@ function teardownMockAudioContext() {
1195
1265
  }
1196
1266
  }
1197
1267
  function captureAudioEvents(context) {
1198
- return [];
1268
+ return context._events || [];
1199
1269
  }
1200
1270
 
1201
1271
  // src/setup/timing.ts
@@ -1487,16 +1557,129 @@ async function captureGameState(page) {
1487
1557
  return {};
1488
1558
  });
1489
1559
  }
1560
+
1561
+ // src/e2e/network.ts
1562
+ var CONDITIONS = {
1563
+ "good": {
1564
+ offline: false,
1565
+ downloadThroughput: 10 * 1024 * 1024,
1566
+ // 10 Mbps
1567
+ uploadThroughput: 5 * 1024 * 1024,
1568
+ // 5 Mbps
1569
+ latency: 20
1570
+ },
1571
+ "slow": {
1572
+ offline: false,
1573
+ downloadThroughput: 500 * 1024,
1574
+ // 500 Kbps
1575
+ uploadThroughput: 500 * 1024,
1576
+ latency: 400
1577
+ },
1578
+ "unstable": {
1579
+ offline: false,
1580
+ downloadThroughput: 1 * 1024 * 1024,
1581
+ uploadThroughput: 1 * 1024 * 1024,
1582
+ latency: 100
1583
+ },
1584
+ "offline": {
1585
+ offline: true,
1586
+ downloadThroughput: 0,
1587
+ uploadThroughput: 0,
1588
+ latency: 0
1589
+ }
1590
+ };
1591
+ function simulateNetworkCondition(condition) {
1592
+ const config = CONDITIONS[condition];
1593
+ return createCustomNetworkCondition(config.latency, 0, 0, config);
1594
+ }
1595
+ function createCustomNetworkCondition(latency, jitter = 0, packetLoss = 0, baseConfig) {
1596
+ return {
1597
+ async apply(page) {
1598
+ const client = await page.context().newCDPSession(page);
1599
+ await client.send("Network.enable");
1600
+ await client.send("Network.emulateNetworkConditions", {
1601
+ offline: baseConfig?.offline || false,
1602
+ latency: latency + Math.random() * jitter,
1603
+ downloadThroughput: baseConfig?.downloadThroughput || -1,
1604
+ uploadThroughput: baseConfig?.uploadThroughput || -1
1605
+ });
1606
+ },
1607
+ async clear(page) {
1608
+ const client = await page.context().newCDPSession(page);
1609
+ await client.send("Network.emulateNetworkConditions", {
1610
+ offline: false,
1611
+ latency: 0,
1612
+ downloadThroughput: -1,
1613
+ uploadThroughput: -1
1614
+ });
1615
+ }
1616
+ };
1617
+ }
1618
+ async function throttleBandwidth(page, bytesPerSecond) {
1619
+ const simulator = createCustomNetworkCondition(0, 0, 0, {
1620
+ offline: false,
1621
+ latency: 0,
1622
+ downloadThroughput: bytesPerSecond,
1623
+ uploadThroughput: bytesPerSecond
1624
+ });
1625
+ await simulator.apply(page);
1626
+ }
1627
+
1628
+ // src/e2e/visual.ts
1629
+ import path from "path";
1630
+ import fs from "fs/promises";
1631
+ async function captureGameScreenshot(page, name, options = {}) {
1632
+ const dir = options.dir || "__screenshots__";
1633
+ const screenshotPath = path.join(dir, `${name}.png`);
1634
+ await fs.mkdir(dir, { recursive: true });
1635
+ return await page.screenshot({
1636
+ path: screenshotPath,
1637
+ fullPage: options.fullPage ?? false,
1638
+ animations: "disabled",
1639
+ caret: "hide"
1640
+ });
1641
+ }
1642
+ async function compareScreenshots(baseline, current, threshold = 0.1) {
1643
+ if (baseline.equals(current)) {
1644
+ return { pixelDiff: 0, matched: true };
1645
+ }
1646
+ return {
1647
+ pixelDiff: -1,
1648
+ // Unknown magnitude
1649
+ matched: false
1650
+ };
1651
+ }
1652
+ function createVisualTestScenario(page, sceneName) {
1653
+ return {
1654
+ async capture(snapshotName) {
1655
+ return await captureGameScreenshot(page, `${sceneName}-${snapshotName}`);
1656
+ },
1657
+ async compare(snapshotName, baselineDir) {
1658
+ const name = `${sceneName}-${snapshotName}`;
1659
+ const current = await captureGameScreenshot(page, name, { dir: "__screenshots__/current" });
1660
+ try {
1661
+ const baselinePath = path.join(baselineDir, `${name}.png`);
1662
+ const baseline = await fs.readFile(baselinePath);
1663
+ return await compareScreenshots(baseline, current);
1664
+ } catch (e) {
1665
+ return { pixelDiff: -1, matched: false };
1666
+ }
1667
+ }
1668
+ };
1669
+ }
1490
1670
  export {
1491
1671
  InputInjector,
1492
1672
  MockPointerLock,
1493
1673
  MockTransport,
1494
1674
  captureAudioEvents,
1495
1675
  captureCanvasDrawCalls,
1676
+ captureGameScreenshot,
1496
1677
  captureGameState,
1678
+ compareScreenshots,
1497
1679
  createBinaryStreamMock,
1498
1680
  createBinaryWriterMock,
1499
1681
  createControlledTimer,
1682
+ createCustomNetworkCondition,
1500
1683
  createEntity,
1501
1684
  createEntityStateFactory,
1502
1685
  createGameStateSnapshotFactory,
@@ -1527,6 +1710,7 @@ export {
1527
1710
  createSpawnContext,
1528
1711
  createStorageTestScenario,
1529
1712
  createTestContext,
1713
+ createVisualTestScenario,
1530
1714
  intersects,
1531
1715
  ladderTrace,
1532
1716
  makeAxisBrush,
@@ -1541,9 +1725,11 @@ export {
1541
1725
  setupNodeEnvironment,
1542
1726
  simulateFrames,
1543
1727
  simulateFramesWithMock,
1728
+ simulateNetworkCondition,
1544
1729
  stairTrace,
1545
1730
  teardownBrowserEnvironment,
1546
1731
  teardownMockAudioContext,
1732
+ throttleBandwidth,
1547
1733
  waitForGameReady
1548
1734
  };
1549
1735
  //# sourceMappingURL=index.js.map