57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
import * as tls from "tls";
|
|||
|
|
import { test, expect } from "@playwright/test";
|
||
|
|
import { BASE, requireAuth } from "./helpers";
|
||
|
|
|
||
|
|
test.describe("WebSocket", () => {
|
||
|
|
// Test WS via raw TLS to avoid browser HTTP/2 and Node.js http module quirks.
|
||
|
|
test("WS handshake with valid token succeeds", async () => {
|
||
|
|
const auth = requireAuth();
|
||
|
|
|
||
|
|
const statusCode = await new Promise<number>((resolve) => {
|
||
|
|
const socket = tls.connect(
|
||
|
|
{ host: "localhost", port: 443, rejectUnauthorized: false },
|
||
|
|
() => {
|
||
|
|
const handshake = [
|
||
|
|
"GET /api/ws HTTP/1.1",
|
||
|
|
"Host: localhost",
|
||
|
|
"Upgrade: websocket",
|
||
|
|
"Connection: Upgrade",
|
||
|
|
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==",
|
||
|
|
"Sec-WebSocket-Version: 13",
|
||
|
|
`Authorization: Bearer ${auth.accessToken!}`,
|
||
|
|
"",
|
||
|
|
"",
|
||
|
|
].join("\r\n");
|
||
|
|
socket.write(handshake);
|
||
|
|
},
|
||
|
|
);
|
||
|
|
let buf = "";
|
||
|
|
socket.on("data", (chunk) => {
|
||
|
|
buf += chunk.toString();
|
||
|
|
const firstLine = buf.split("\r\n")[0] ?? "";
|
||
|
|
const m = firstLine.match(/HTTP\/1\.\d\s+(\d+)/);
|
||
|
|
if (m) {
|
||
|
|
socket.destroy();
|
||
|
|
resolve(parseInt(m[1], 10));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
socket.on("error", () => resolve(0));
|
||
|
|
setTimeout(() => { socket.destroy(); resolve(0); }, 8000);
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(statusCode, `WS upgrade returned ${statusCode}`).toBe(101);
|
||
|
|
});
|
||
|
|
|
||
|
|
test("WS handshake without token is rejected", async ({ page }) => {
|
||
|
|
const result = await page.evaluate((wsUrl) => {
|
||
|
|
return new Promise<{ code: number }>((resolve) => {
|
||
|
|
const ws = new WebSocket(wsUrl);
|
||
|
|
ws.onclose = (e) => resolve({ code: e.code });
|
||
|
|
setTimeout(() => resolve({ code: -1 }), 6000);
|
||
|
|
});
|
||
|
|
}, BASE.replace("https", "wss") + "/api/ws");
|
||
|
|
|
||
|
|
expect(result.code).not.toBe(1000);
|
||
|
|
});
|
||
|
|
});
|