Ctrl K
ComunidadGuías…

test/realtime-smoke.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"use strict";

const assert = require("assert");
const fs = require("fs");
const http = require("http");
const https = require("https");
const path = require("path");
const WebSocket = require("ws");

const insecure = new https.Agent({ rejectUnauthorized: false });
const useHttp = process.env.C9_TEST_HTTP === "1";
const origin = (useHttp ? "http" : "https") + "://127.0.0.1:1337";
const base = process.env.C9_TEST_WS || (useHttp ? "ws" : "wss") + "://127.0.0.1:1337";
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const env = Object.assign({}, process.env);
try {
  fs.readFileSync(path.join(__dirname, "..", ".env"), "utf8").split(/\r?\n/).forEach((line) => {
    const i = line.indexOf("=");
    if (i > 0 && env[line.slice(0, i)] == null) env[line.slice(0, i)] = line.slice(i + 1);
  });
} catch (error) {
  if (!env.AUTH_USER || !env.AUTH_PASS) throw error;
}

function login() {
  return new Promise((resolve, reject) => {
    const body = "username=" + encodeURIComponent(env.AUTH_USER) + "&password=" + encodeURIComponent(env.AUTH_PASS);
    const mod = useHttp ? http : https;
    const req = mod.request(origin + "/login", {
      method: "POST",
      agent: useHttp ? undefined : insecure,
      rejectUnauthorized: false,
      headers: { "Content-Type": "application/x-www-form-urlencoded", "Content-Length": Buffer.byteLength(body) },
    }, (res) => {
      const cookie = (res.headers["set-cookie"] || [])[0];
      if (!cookie) return reject(new Error("login cookie missing"));
      resolve(cookie.split(";")[0]);
    });
    req.on("error", reject); req.end(body);
  });
}

function connect(pathname, cookie) {
  return new Promise((resolve, reject) => {
    const ws = new WebSocket(base + pathname, { headers: { Cookie: cookie }, rejectUnauthorized: false });
    const timer = setTimeout(() => reject(new Error("connect timeout: " + pathname)), 5000);
    ws.once("open", () => { clearTimeout(timer); resolve(ws); });
    ws.once("error", reject);
  });
}

function nextJson(ws, wanted) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => reject(new Error("message timeout: " + wanted)), 7000);
    const onMessage = (raw) => {
      let msg; try { msg = JSON.parse(raw.toString()); } catch (e) { return; }
      if (msg.type !== wanted) return;
      clearTimeout(timer);
      ws.removeListener("message", onMessage);
      resolve(msg);
    };
    ws.on("message", onMessage);
  });
}

async function main() {
  const cookie = await login();
  const a = await connect("/sync", cookie);
  const snapshotA = await nextJson(a, "snapshot");
  const b = await connect("/sync", cookie);
  const snapshotB = await nextJson(b, "snapshot");
  assert.deepStrictEqual(snapshotA.state.layout, snapshotB.state.layout);

  a.send(JSON.stringify({ type: "terminal-create", requestId: "smoke-term", cwd: "" }));
  const created = await nextJson(a, "terminal-created");
  const id = created.terminal.id;
  const ta = await connect("/terminal?id=" + encodeURIComponent(id), cookie);
  const tb = await connect("/terminal?id=" + encodeURIComponent(id), cookie);
  const token = "C9_MULTI_" + Date.now();
  let outA = "", outB = "";
  ta.on("message", (d) => { outA += d.toString(); });
  tb.on("message", (d) => { outB += d.toString(); });
  ta.send("echo " + token + "\n");
  for (let i = 0; i < 40 && (!outA.includes(token) || !outB.includes(token)); i++) await wait(100);
  assert.ok(outA.includes(token), "terminal A did not receive shared output");
  assert.ok(outB.includes(token), "terminal B did not receive shared output");

  a.send(JSON.stringify({ type: "terminal-close", id }));
  await wait(150);
  ta.close(); tb.close(); a.close(); b.close();
  console.log("realtime-smoke: ok");
}

main().catch((error) => {
  console.error(error.stack || error);
  process.exit(1);
});