mirror of
https://github.com/browseros-ai/BrowserOS.git
synced 2026-05-21 21:05:09 +00:00
* fix: remove all .js in imports * fix: update claude mode to use right import * fix: remove addition in main package.json
122 lines
2.7 KiB
TypeScript
122 lines
2.7 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 BrowserOS
|
|
*/
|
|
import http, {
|
|
type IncomingMessage,
|
|
type Server,
|
|
type ServerResponse,
|
|
} from 'node:http'
|
|
import { after, afterEach, before } from 'node:test'
|
|
|
|
import { html } from '../__helpers__/utils'
|
|
|
|
class TestServer {
|
|
#port: number
|
|
#server: Server
|
|
|
|
static randomPort() {
|
|
/**
|
|
* Some ports are restricted by Chromium and will fail to connect.
|
|
* We start after the restricted ports range.
|
|
*
|
|
* https://source.chromium.org/chromium/chromium/src/+/main:net/base/port_util.cc;l=107?q=kRestrictedPorts&ss=chromium
|
|
*/
|
|
const min = 10101
|
|
const max = 20202
|
|
return Math.floor(Math.random() * (max - min + 1) + min)
|
|
}
|
|
|
|
#routes: Record<string, (req: IncomingMessage, res: ServerResponse) => void> =
|
|
{}
|
|
|
|
constructor(port: number) {
|
|
this.#port = port
|
|
this.#server = http.createServer((req, res) => this.#handle(req, res))
|
|
}
|
|
|
|
get baseUrl(): string {
|
|
return `http://localhost:${this.#port}`
|
|
}
|
|
|
|
getRoute(path: string) {
|
|
if (!this.#routes[path]) {
|
|
throw new Error(`Route ${path} was not setup.`)
|
|
}
|
|
return `${this.baseUrl}${path}`
|
|
}
|
|
|
|
addHtmlRoute(path: string, htmlContent: string) {
|
|
if (this.#routes[path]) {
|
|
throw new Error(`Route ${path} was already setup.`)
|
|
}
|
|
this.#routes[path] = (_req: IncomingMessage, res: ServerResponse) => {
|
|
res.setHeader('Content-Type', 'text/html; charset=utf-8')
|
|
res.statusCode = 200
|
|
res.end(htmlContent)
|
|
}
|
|
}
|
|
|
|
addRoute(
|
|
path: string,
|
|
handler: (req: IncomingMessage, res: ServerResponse) => void,
|
|
) {
|
|
if (this.#routes[path]) {
|
|
throw new Error(`Route ${path} was already setup.`)
|
|
}
|
|
this.#routes[path] = handler
|
|
}
|
|
|
|
#handle(req: IncomingMessage, res: ServerResponse) {
|
|
const url = req.url ?? ''
|
|
const routeHandler = this.#routes[url]
|
|
|
|
if (routeHandler) {
|
|
routeHandler(req, res)
|
|
} else {
|
|
res.writeHead(404, { 'Content-Type': 'text/html' })
|
|
res.end(
|
|
html`<h1>404 - Not Found</h1>
|
|
<p>The requested page does not exist.</p>`,
|
|
)
|
|
}
|
|
}
|
|
|
|
restore() {
|
|
this.#routes = {}
|
|
}
|
|
|
|
start(): Promise<void> {
|
|
return new Promise((res) => {
|
|
this.#server.listen(this.#port, res)
|
|
})
|
|
}
|
|
|
|
stop(): Promise<void> {
|
|
return new Promise((res, rej) => {
|
|
this.#server.close((err) => {
|
|
if (err) {
|
|
rej(err)
|
|
} else {
|
|
res()
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
export function serverHooks() {
|
|
const server = new TestServer(TestServer.randomPort())
|
|
before(async () => {
|
|
await server.start()
|
|
})
|
|
after(async () => {
|
|
await server.stop()
|
|
})
|
|
afterEach(() => {
|
|
server.restore()
|
|
})
|
|
|
|
return server
|
|
}
|