mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-14 16:14:28 +00:00
Compare commits
2 Commits
fix/auto-i
...
fix/tests
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e78bf58d41 | ||
|
|
a1c83a4b9c |
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -54,6 +54,10 @@ jobs:
|
||||
command: (cd apps/server && bun run test:integration)
|
||||
junit_path: test-results/server-integration.xml
|
||||
needs_browser: true
|
||||
- suite: server-lib
|
||||
command: (cd apps/server && bun run test:lib)
|
||||
junit_path: test-results/server-lib.xml
|
||||
needs_browser: false
|
||||
- suite: server-sdk
|
||||
command: (cd apps/server && bun run test:sdk)
|
||||
junit_path: test-results/server-sdk.xml
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"test:cdp": "bun run test:browser",
|
||||
"test:core": "bun run ./tests/__helpers__/run-test-group.ts core",
|
||||
"test:integration": "bun run ./tests/__helpers__/run-test-group.ts integration",
|
||||
"test:lib": "bun run ./tests/__helpers__/run-test-group.ts lib",
|
||||
"test:root": "bun run ./tests/__helpers__/run-test-group.ts root",
|
||||
"test:sdk": "bun run ./tests/__helpers__/run-test-group.ts sdk",
|
||||
"test:skills": "bun run ./tests/__helpers__/run-test-group.ts skills",
|
||||
|
||||
@@ -17,7 +17,7 @@ export const TERMINAL_WS_PATH = '/terminal/ws'
|
||||
interface TerminalRouteDeps {
|
||||
containerName: string
|
||||
limaHome: string
|
||||
limactlPath: string
|
||||
limactlPath: string | (() => string)
|
||||
vmName: string
|
||||
}
|
||||
|
||||
@@ -39,16 +39,20 @@ function sendExit(ws: { send(data: string): void }, exitCode: number): void {
|
||||
safeSend(ws, serializeTerminalServerMessage({ type: 'exit', exitCode }))
|
||||
}
|
||||
|
||||
function createSocketEvents(deps: TerminalRouteDeps) {
|
||||
export function createTerminalSocketEvents(deps: TerminalRouteDeps) {
|
||||
let session: TerminalSession | null = null
|
||||
|
||||
return {
|
||||
onOpen(_event: Event, ws: { send(data: string): void; close(): void }) {
|
||||
try {
|
||||
const limactlPath =
|
||||
typeof deps.limactlPath === 'function'
|
||||
? deps.limactlPath()
|
||||
: deps.limactlPath
|
||||
session = createTerminalSession({
|
||||
containerName: deps.containerName,
|
||||
limaHome: deps.limaHome,
|
||||
limactlPath: deps.limactlPath,
|
||||
limactlPath,
|
||||
vmName: deps.vmName,
|
||||
workingDir: TERMINAL_HOME_DIR,
|
||||
onOutput(data) {
|
||||
@@ -93,6 +97,6 @@ function createSocketEvents(deps: TerminalRouteDeps) {
|
||||
export function createTerminalRoutes(deps: TerminalRouteDeps) {
|
||||
return new Hono<Env>().get(
|
||||
'/ws',
|
||||
upgradeWebSocket(() => createSocketEvents(deps)),
|
||||
upgradeWebSocket(() => createTerminalSocketEvents(deps)),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ export async function createHttpServer(config: HttpServerConfig) {
|
||||
createTerminalRoutes({
|
||||
containerName: OPENCLAW_GATEWAY_CONTAINER_NAME,
|
||||
limaHome: getLimaHomeDir(),
|
||||
limactlPath: resolveBundledLimactl(resourcesDir),
|
||||
limactlPath: () => resolveBundledLimactl(resourcesDir),
|
||||
vmName: VM_NAME,
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -48,15 +48,15 @@ function listRootTestTargets(): string[] {
|
||||
.sort((left, right) => left.localeCompare(right))
|
||||
}
|
||||
|
||||
function listAllGroups(): string[] {
|
||||
const groups = [...listDirectoryGroups()]
|
||||
export function listAllGroups(): string[] {
|
||||
const groups = new Set(listDirectoryGroups())
|
||||
if (existsSync(resolve(testsRoot, 'server.integration.test.ts'))) {
|
||||
groups.push('integration')
|
||||
groups.add('integration')
|
||||
}
|
||||
if (listRootTestTargets().length > 0) {
|
||||
groups.push('root')
|
||||
groups.add('root')
|
||||
}
|
||||
return groups
|
||||
return [...groups]
|
||||
}
|
||||
|
||||
function listAvailableGroupNames(): string[] {
|
||||
@@ -75,14 +75,19 @@ function getCompositeGroupMembers(group: string): string[] | null {
|
||||
return null
|
||||
}
|
||||
|
||||
function getAtomicGroupTargets(group: string): string[] {
|
||||
export function getAtomicGroupTargets(group: string): string[] {
|
||||
if (group === 'cdp') {
|
||||
return getAtomicGroupTargets('browser')
|
||||
}
|
||||
if (group === 'integration') {
|
||||
return existsSync(resolve(testsRoot, 'server.integration.test.ts'))
|
||||
? ['./tests/server.integration.test.ts']
|
||||
: []
|
||||
const targets: string[] = []
|
||||
if (existsSync(resolve(testsRoot, 'integration'))) {
|
||||
targets.push('./tests/integration')
|
||||
}
|
||||
if (existsSync(resolve(testsRoot, 'server.integration.test.ts'))) {
|
||||
targets.push('./tests/server.integration.test.ts')
|
||||
}
|
||||
return targets
|
||||
}
|
||||
if (group === 'root') {
|
||||
return listRootTestTargets()
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 BrowserOS
|
||||
*/
|
||||
|
||||
import { afterEach, describe, expect, it, mock } from 'bun:test'
|
||||
|
||||
describe('createTerminalSocketEvents', () => {
|
||||
afterEach(() => {
|
||||
mock.restore()
|
||||
})
|
||||
|
||||
it('resolves limactl only when a terminal socket opens', async () => {
|
||||
const close = mock(() => {})
|
||||
const send = mock(() => {})
|
||||
const session = {
|
||||
close: mock(() => {}),
|
||||
resize: mock(() => {}),
|
||||
writeInput: mock(() => {}),
|
||||
}
|
||||
const createTerminalSession = mock(() => session)
|
||||
const actualTerminalSession = await import(
|
||||
'../../../src/api/services/terminal/terminal-session'
|
||||
)
|
||||
|
||||
mock.module('../../../src/api/services/terminal/terminal-session', () => ({
|
||||
...actualTerminalSession,
|
||||
createTerminalSession,
|
||||
}))
|
||||
|
||||
const { createTerminalSocketEvents } = await import(
|
||||
'../../../src/api/routes/terminal'
|
||||
)
|
||||
const resolveLimactlPath = mock(() => '/tmp/fake-limactl')
|
||||
|
||||
const events = createTerminalSocketEvents({
|
||||
containerName: 'gateway',
|
||||
limaHome: '/tmp/lima',
|
||||
limactlPath: resolveLimactlPath,
|
||||
vmName: 'browseros-vm',
|
||||
})
|
||||
|
||||
expect(resolveLimactlPath).not.toHaveBeenCalled()
|
||||
|
||||
events.onOpen(new Event('open'), { send, close })
|
||||
|
||||
expect(resolveLimactlPath).toHaveBeenCalledTimes(1)
|
||||
expect(createTerminalSession).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
containerName: 'gateway',
|
||||
limaHome: '/tmp/lima',
|
||||
limactlPath: '/tmp/fake-limactl',
|
||||
vmName: 'browseros-vm',
|
||||
workingDir: actualTerminalSession.TERMINAL_HOME_DIR,
|
||||
}),
|
||||
)
|
||||
expect(close).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('sends an error and closes when the limactl resolver throws', async () => {
|
||||
const close = mock(() => {})
|
||||
const send = mock(() => {})
|
||||
const createTerminalSession = mock(() => {
|
||||
throw new Error('should not start a session')
|
||||
})
|
||||
const actualTerminalSession = await import(
|
||||
'../../../src/api/services/terminal/terminal-session'
|
||||
)
|
||||
|
||||
mock.module('../../../src/api/services/terminal/terminal-session', () => ({
|
||||
...actualTerminalSession,
|
||||
createTerminalSession,
|
||||
}))
|
||||
|
||||
const { createTerminalSocketEvents } = await import(
|
||||
'../../../src/api/routes/terminal'
|
||||
)
|
||||
const events = createTerminalSocketEvents({
|
||||
containerName: 'gateway',
|
||||
limaHome: '/tmp/lima',
|
||||
limactlPath: () => {
|
||||
throw new Error('limactl not found')
|
||||
},
|
||||
vmName: 'browseros-vm',
|
||||
})
|
||||
|
||||
events.onOpen(new Event('open'), { send, close })
|
||||
|
||||
expect(createTerminalSession).not.toHaveBeenCalled()
|
||||
expect(send).toHaveBeenCalledWith(
|
||||
JSON.stringify({ type: 'error', message: 'limactl not found' }),
|
||||
)
|
||||
expect(close).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
@@ -4,7 +4,12 @@
|
||||
*/
|
||||
|
||||
import { describe, expect, it } from 'bun:test'
|
||||
import { buildTestCommand, withTestEnv } from './__helpers__/run-test-group'
|
||||
import {
|
||||
buildTestCommand,
|
||||
getAtomicGroupTargets,
|
||||
listAllGroups,
|
||||
withTestEnv,
|
||||
} from './__helpers__/run-test-group'
|
||||
|
||||
describe('withTestEnv', () => {
|
||||
it('defaults NODE_ENV to test when absent', () => {
|
||||
@@ -27,3 +32,22 @@ describe('buildTestCommand', () => {
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('test groups', () => {
|
||||
it('includes the lib tests in the group list', () => {
|
||||
expect(listAllGroups()).toContain('lib')
|
||||
})
|
||||
|
||||
it('runs root and directory integration tests in the integration group', () => {
|
||||
expect(getAtomicGroupTargets('integration')).toEqual([
|
||||
'./tests/integration',
|
||||
'./tests/server.integration.test.ts',
|
||||
])
|
||||
})
|
||||
|
||||
it('does not duplicate group names', () => {
|
||||
const groups = listAllGroups()
|
||||
|
||||
expect(new Set(groups).size).toBe(groups.length)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user