Radish alpha
r
Radicle web interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
Allow httpd API ports to be generated randomly.
Sebastian Martinez committed 2 years ago
commit db94969f8a17c0f2af271e3c7bc71070f15ffb90
parent bde2d97c9b428ccbe741adbcbd70fc2914979713
6 files changed +72 -37
modified httpd-client/tests/support/globalSetup.ts
@@ -52,7 +52,7 @@ export default async function globalSetup(): Promise<() => void> {
    console.log("Running tests");
    await palm.stopNode();
  } else {
-
    await startPalmHttpd();
+
    await startPalmHttpd(8080);
  }

  return () => killAllProcesses();
modified tests/e2e/project/commits.spec.ts
@@ -11,12 +11,12 @@ import { createProject } from "@tests/support/project";

test("peer and branch switching", async ({ page }) => {
  await page.goto(sourceBrowsingUrl);
-
  await page.locator('role=link[name="6 commits"]').click();
+
  await page.getByRole("link", { name: "6 commits" }).click();

  // Alice's peer.
  {
    await page.getByTitle("Change peer").click();
-
    await page.locator(`text=${aliceRemote}`).click();
+
    await page.getByText(aliceRemote).click();
    await expect(page.getByTitle("Change peer")).toHaveText(
      `  did:key:${aliceRemote
        .substring(8)
@@ -37,7 +37,7 @@ test("peer and branch switching", async ({ page }) => {
    await expect(earliestCommit).toContainText("36d5bbe");

    await page.getByTitle("Change branch").click();
-
    await page.locator("text=feature/branch").click();
+
    await page.getByText("feature/branch").click();

    await expect(page.getByTitle("Current branch")).toContainText(
      "feature/branch 1aded56",
@@ -46,7 +46,7 @@ test("peer and branch switching", async ({ page }) => {
    await expect(page.locator(".history .teaser")).toHaveCount(9);

    await page.getByTitle("Change branch").click();
-
    await page.locator("text=orphaned-branch").click();
+
    await page.getByText("orphaned-branch").click();

    await expect(page.getByTitle("Current branch")).toContainText(
      "orphaned-branch af3641c",
@@ -58,7 +58,7 @@ test("peer and branch switching", async ({ page }) => {
  // Bob's peer.
  {
    await page.getByTitle("Change peer").click();
-
    await page.locator(`text=${bobRemote}`).click();
+
    await page.getByText(bobRemote).click();
    await expect(page.getByTitle("Change peer")).toContainText(
      ` did:key:${bobRemote.substring(8).substring(0, 6)}…${bobRemote.slice(
        -6,
@@ -89,7 +89,7 @@ test("peer and branch switching", async ({ page }) => {

test("expand commit message", async ({ page }) => {
  await page.goto(sourceBrowsingUrl);
-
  await page.locator('role=link[name="6 commits"]').click();
+
  await page.getByRole("link", { name: "6 commits" }).click();
  const commitToggle = page
    .locator("div")
    .filter({ hasText: /^Add a C source file and its binary …$/ })
@@ -117,10 +117,10 @@ test("relative timestamps", async ({ page }) => {
  });

  await page.goto(sourceBrowsingUrl);
-
  await page.locator('role=link[name="6 commits"]').click();
+
  await page.getByRole("link", { name: "6 commits" }).click();

  await page.getByTitle("Change peer").click();
-
  await page.locator(`text=${bobRemote}`).click();
+
  await page.getByText(bobRemote).click();
  await expect(page.getByTitle("Change peer")).toHaveText(
    `did:key:${bobRemote.substring(8).substring(0, 6)}…${bobRemote.slice(-6)}`,
  );
@@ -138,12 +138,12 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
    name: "alice",
    gitOptions: gitOptions["alice"],
  });
-
  await alice.startHttpd(8090);
+
  await alice.startHttpd();
  await alice.startNode();
  const { rid, projectFolder } = await createProject(alice, "alice-project");
-
  await page.goto(`/seeds/127.0.0.1:8090/${rid}`);
-
  await page.locator('role=link[name="1 commit"]').click();
-
  await expect(page).toHaveURL(`/seeds/127.0.0.1:8090/${rid}/history`);
+
  await page.goto(`${alice.uiUrl()}/${rid}`);
+
  await page.getByRole("link", { name: "1 commit" }).click();
+
  await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}/history`);

  await alice.git(["commit", "--allow-empty", "--message", "first change"], {
    cwd: projectFolder,
@@ -152,13 +152,13 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
    cwd: projectFolder,
  });
  await page.reload();
-
  await expect(page).toHaveURL(`/seeds/127.0.0.1:8090/${rid}/history`);
-
  await expect(page.locator('role=link[name="2 commits"]')).toBeVisible();
+
  await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}/history`);
+
  await expect(page.getByRole("link", { name: "2 commits" })).toBeVisible();
  await expect(page.getByTitle("Current branch")).toContainText("main 516fa74");

-
  await page.locator("text=alice-project").click();
-
  await expect(page).toHaveURL(`/seeds/127.0.0.1:8090/${rid}`);
-
  await page.locator('role=link[name="2 commits"]').click();
+
  await page.getByText("alice-project").click();
+
  await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}`);
+
  await page.getByRole("link", { name: "2 commits" }).click();

  await alice.git(
    [
@@ -175,8 +175,8 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
    cwd: projectFolder,
  });
  await page.reload();
-
  await expect(page).toHaveURL(`/seeds/127.0.0.1:8090/${rid}/history`);
-
  await expect(page.locator('role=link[name="3 commits"]')).toHaveText(
+
  await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}/history`);
+
  await expect(page.getByRole("link", { name: "3 commits" })).toHaveText(
    "3 commits",
  );
  await expect(page.getByTitle("Current branch")).toContainText("main bb9089a");
modified tests/e2e/project/issues.spec.ts
@@ -48,7 +48,7 @@ test("test issue editing failing", async ({ page, authenticatedPeer }) => {
  );

  await page.goto(
-
    `/seeds/127.0.0.1:8070/${rid}/issues/d316f7a90a40dacbfb8728044bad50c9f71d44ba`,
+
    `${authenticatedPeer.uiUrl()}/${rid}/issues/d316f7a90a40dacbfb8728044bad50c9f71d44ba`,
  );

  await page.getByPlaceholder("Leave your comment").fill("This is a comment");
@@ -62,7 +62,9 @@ test("go through the entire ui issue flow", async ({
}) => {
  const { rid } = await createProject(authenticatedPeer, "commenting");

-
  await page.goto(`/seeds/127.0.0.1:8070/${rid}`);
+
  await page.goto(
+
    `/seeds/${authenticatedPeer.httpdBaseUrl.hostname}:${authenticatedPeer.httpdBaseUrl.port}/${rid}`,
+
  );
  await page.getByRole("link", { name: "0 issues" }).click();
  await page.getByRole("link", { name: "New issue" }).click();
  await page.getByPlaceholder("Title").fill("This is a title");
modified tests/support/fixtures.ts
@@ -165,18 +165,20 @@ export const test = base.extend<{
      gitOptions: gitOptions["bob"],
    });

-
    await peer.startHttpd(8070);
+
    await peer.startHttpd();
    await peer.startNode();
    await page.goto("/");
    await page.getByRole("button", { name: "radicle.local" }).click();
-
    await page.locator('input[name="port"]').fill("8070");
+
    await page
+
      .locator('input[name="port"]')
+
      .fill(peer.httpdBaseUrl.port.toString());
    await page.locator('input[name="port"]').press("Enter");
    const { stdout } = await peer.rad([
      "web",
      "--frontend",
      "http://localhost:3001",
      "--backend",
-
      "http://127.0.0.1:8070",
+
      `${peer.httpdBaseUrl.scheme}://${peer.httpdBaseUrl.hostname}:${peer.httpdBaseUrl.port}`,
      "--json",
    ]);
    const result = authSchema.safeParse(JSON.parse(stdout));
@@ -191,7 +193,7 @@ export const test = base.extend<{

    await use(peer);

-
    await peer.stopHttpd(8070);
+
    await peer.stopHttpd();
    await peer.stopNode();
  },

@@ -256,13 +258,13 @@ export function appConfigWithFixture() {
  };
}

-
export async function startPalmHttpd() {
+
export async function startPalmHttpd(httpdPort: number) {
  const peerManager = await createPeerManager({
    dataDir: Path.resolve(Path.join(tmpDir, "peers")),
    outputLog: FsSync.createWriteStream(Path.resolve(Path.join(tmpDir, "log"))),
  });
  const palm = await peerManager.startPeer({ name: "palm" });
-
  await palm.startHttpd(8080);
+
  await palm.startHttpd(httpdPort);
}

export async function createSourceBrowsingFixture(
@@ -611,7 +613,6 @@ export const markdownRid = "rad:z2tchH2Ti4LxRKdssPQYs6VHE5rsg";
export const sourceBrowsingUrl = `/seeds/127.0.0.1/${sourceBrowsingRid}`;
export const cobUrl = `/seeds/127.0.0.1/${cobRid}`;
export const markdownUrl = `/seeds/127.0.0.1/${markdownRid}`;
-
export const seedPort = 8080;
export const seedRemote = "z6MktULudTtAsAhRegYPiZ6631RV3viv12qd4GQF8z1xB22S";
export const gitOptions = {
  alice: {
modified tests/support/globalSetup.ts
@@ -61,7 +61,7 @@ export default async function globalSetup(): Promise<() => void> {
    console.log("Running tests");
    await palm.stopNode();
  } else {
-
    await startPalmHttpd();
+
    await startPalmHttpd(8080);
  }

  return () => killAllProcesses();
modified tests/support/peerManager.ts
@@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/naming-convention */
+
import type { BaseUrl } from "@httpd-client";
import type { ExecaChildProcess, Options } from "execa";

import * as Fs from "node:fs/promises";
@@ -115,6 +116,7 @@ export class RadiclePeer {
  #outputLog: Stream.Writable;
  #gitOptions?: Record<string, string>;
  #listenSocketAddr?: string;
+
  #httpdBaseUrl?: BaseUrl;
  #nodeProcess?: ExecaChildProcess;
  #httpdProcess?: ExecaChildProcess;

@@ -184,25 +186,42 @@ export class RadiclePeer {
    });
  }

-
  public async startHttpd(port: number) {
+
  public async startHttpd(port?: number): Promise<void> {
+
    if (!port) {
+
      port = await getPort();
+
    }
+
    this.#httpdBaseUrl = {
+
      hostname: "127.0.0.1",
+
      port,
+
      scheme: "http",
+
    };
    this.#httpdProcess = this.spawn("radicle-httpd", [
      "--listen",
-
      `0.0.0.0:${port}`,
+
      `${this.#httpdBaseUrl.hostname}:${this.#httpdBaseUrl.port}`,
    ]);

    await waitOn({
-
      resources: [`tcp:127.0.0.1:${port}`],
+
      resources: [
+
        `tcp:${this.#httpdBaseUrl.hostname}:${this.#httpdBaseUrl.port}`,
+
      ],
      timeout: 7000,
    });
  }

-
  public async stopHttpd(port: number) {
+
  public async stopHttpd() {
+
    if (!this.#httpdBaseUrl || !this.#httpdProcess) {
+
      throw new Error("No httpd service running");
+
    }
    this.#httpdProcess?.kill("SIGTERM");

    await waitOn({
-
      resources: [`tcp:127.0.0.1:${port}`],
+
      resources: [
+
        `tcp:${this.#httpdBaseUrl.hostname}:${this.#httpdBaseUrl.port}`,
+
      ],
      reverse: true,
    });
+

+
    this.#httpdBaseUrl = undefined;
  }

  public async startNode(params?: {
@@ -312,10 +331,23 @@ export class RadiclePeer {
  }

  public uiUrl(): string {
-
    return `/seeds/127.0.0.1:8080`;
+
    if (!this.#httpdBaseUrl) {
+
      throw new Error("No httpd service running");
+
    }
+

+
    return `/seeds/${this.#httpdBaseUrl.hostname}:${this.#httpdBaseUrl.port}`;
  }
+

  public ridUrl(rid: string): string {
-
    return `/seeds/127.0.0.1:8080/${rid}`;
+
    return `/seeds/${this.httpdBaseUrl.hostname}:${this.httpdBaseUrl.port}/${rid}`;
+
  }
+

+
  public get httpdBaseUrl(): BaseUrl {
+
    if (!this.#httpdBaseUrl) {
+
      throw new Error("No httpd service running");
+
    }
+

+
    return this.#httpdBaseUrl;
  }

  public git(args: string[] = [], opts?: Options): ExecaChildProcess {