Added basic tests for testing a real websocket

This commit is contained in:
Niklas Jensen
2025-12-30 19:33:30 +01:00
committed by nikguin04
parent c4d3c8966c
commit 8098dcec9b
5 changed files with 169 additions and 15 deletions
+6 -6
View File
@@ -1,8 +1,8 @@
declare module 'app-env' {
interface ENV {
VITE_USE_HOST_NAME: boolean
}
declare module "app-env" {
interface ENV {
VITE_USE_HOST_NAME: boolean;
}
const appEnv: ENV
export default appEnv
const appEnv: ENV;
export default appEnv;
}
+3 -1
View File
@@ -25,6 +25,7 @@
"@sveltejs/vite-plugin-svelte": "^6.2.1",
"@types/eslint": "^9.6.1",
"@types/three": "^0.180.0",
"@types/ws": "^8.18.1",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/parser": "^8.46.0",
"autoprefixer": "^10.4.21",
@@ -44,7 +45,8 @@
"typescript-eslint": "^8.51.0",
"unplugin-icons": "^22.4.2",
"vite": "^7.1.9",
"vitest": "^3.2.4"
"vitest": "^3.2.4",
"ws": "^8.18.3"
},
"type": "module",
"dependencies": {
+14 -3
View File
@@ -87,6 +87,9 @@ importers:
'@types/three':
specifier: ^0.180.0
version: 0.180.0
'@types/ws':
specifier: ^8.18.1
version: 8.18.1
'@typescript-eslint/eslint-plugin':
specifier: ^8.46.0
version: 8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
@@ -147,6 +150,9 @@ importers:
vitest:
specifier: ^3.2.4
version: 3.2.4(@types/node@24.7.1)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(yaml@2.8.1)
ws:
specifier: ^8.18.3
version: 8.18.3
packages:
@@ -763,6 +769,9 @@ packages:
'@types/webxr@0.5.24':
resolution: {integrity: sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==}
'@types/ws@8.18.1':
resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==}
'@typescript-eslint/eslint-plugin@8.46.0':
resolution: {integrity: sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -2720,7 +2729,6 @@ snapshots:
'@types/node@24.7.1':
dependencies:
undici-types: 7.14.0
optional: true
'@types/stats.js@0.17.4': {}
@@ -2736,6 +2744,10 @@ snapshots:
'@types/webxr@0.5.24': {}
'@types/ws@8.18.1':
dependencies:
'@types/node': 24.7.1
'@typescript-eslint/eslint-plugin@8.46.0(@typescript-eslint/parser@8.46.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
@@ -3999,8 +4011,7 @@ snapshots:
ufo@1.6.1: {}
undici-types@7.14.0:
optional: true
undici-types@7.14.0: {}
unplugin-icons@22.4.2(svelte@5.39.11):
dependencies:
+135
View File
@@ -0,0 +1,135 @@
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { WebSocketServer } from 'ws'
import { socket } from '../../src/lib/stores/socket'
import { IMUData, RSSIData, WebsocketMessage } from '../../src/lib/platform_shared/websocket_message'
// Helper function to create encoded WebSocket messages
function createEncodedMessage(messageType: 'imu' | 'rssi' | 'mode', data: any): Uint8Array {
const message: any = {}
message[messageType] = data
const wsMessage = WebsocketMessage.create(message)
return WebsocketMessage.encode(wsMessage).finish()
}
describe.sequential('WebSocket Integration Tests', () => {
let wss: WebSocketServer
let TEST_PORT = 8765
beforeEach(async () => {
// Use a different port for each test to avoid conflicts
TEST_PORT++
// Create real WebSocket server
wss = new WebSocketServer({ port: TEST_PORT })
// Wait for server to start
await new Promise<void>((resolve) => {
wss.on('listening', () => resolve())
})
})
afterEach(async () => {
// Close all connections and server
wss.clients.forEach((client) => client.close())
await new Promise<void>((resolve) => {
wss.close(() => resolve())
})
// Wait a bit for cleanup
await new Promise(resolve => setTimeout(resolve, 100))
})
it('should connect to WebSocket server', async () => {
socket.init(`ws://localhost:${TEST_PORT}`)
// Wait for connection
await new Promise(resolve => setTimeout(resolve, 100))
let isConnected = false
socket.subscribe(value => {
isConnected = value
})()
expect(isConnected).toBe(true)
})
it('should receive and decode IMU data from server', async () => {
let receivedIMUData: any = null
// Subscribe to IMU messages before connecting
const unsubscribe = socket.on(IMUData, (data) => {
receivedIMUData = data
})
// Connect socket
socket.init(`ws://localhost:${TEST_PORT}`)
// Wait for client to connect
await new Promise<void>((resolve) => {
wss.on('connection', (ws) => {
// Server sends IMU data to client
const imuPayload = {
x: 1.5,
y: 2.5,
z: 3.5,
temp: 25.0
}
const encodedMessage = createEncodedMessage('imu', imuPayload)
ws.send(encodedMessage)
setTimeout(resolve, 50)
})
})
expect(receivedIMUData).toBeDefined()
expect(receivedIMUData.imu?.x).toBe(1.5)
expect(receivedIMUData.imu?.y).toBe(2.5)
expect(receivedIMUData.imu?.z).toBe(3.5)
expect(receivedIMUData.imu?.temp).toBe(25.0)
unsubscribe()
})
})
describe('WebsocketMessage Protobuf Encoding/Decoding', () => {
it('should encode and decode IMU data correctly', () => {
const imuData = {
x: 1.5,
y: 2.5,
z: 3.5,
temp: 25.0
}
const encoded = IMUData.encode(imuData).finish()
const decoded = IMUData.decode(encoded)
expect(decoded.x).toBe(imuData.x)
expect(decoded.y).toBe(imuData.y)
expect(decoded.z).toBe(imuData.z)
expect(decoded.temp).toBe(imuData.temp)
})
it('should encode and decode complete WebsocketMessage', () => {
const original = WebsocketMessage.create({
imu: {
x: 1.5,
y: 2.5,
z: 3.5,
temp: 25.0
}
})
const encoded = WebsocketMessage.encode(original).finish()
const decoded = WebsocketMessage.decode(encoded)
expect(decoded.imu).toBeDefined()
expect(decoded.imu?.x).toBe(1.5)
expect(decoded.imu?.y).toBe(2.5)
expect(decoded.imu?.z).toBe(3.5)
expect(decoded.imu?.temp).toBe(25.0)
})
})
+11 -5
View File
@@ -1,11 +1,17 @@
import { defineConfig, UserConfigExport } from 'vitest/config'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import path from 'path'
const config: UserConfigExport = {
plugins: [svelte()],
test: {
globals: true,
environment: 'jsdom'
}
plugins: [svelte()],
resolve: {
alias: {
$lib: path.resolve(__dirname, './src/lib')
}
},
test: {
globals: true,
environment: 'jsdom'
}
}
export default defineConfig(config)