diff --git a/httpd-client/tests/support/globalSetup.ts b/httpd-client/tests/support/globalSetup.ts index aea9f2283..6de96b6a5 100644 --- a/httpd-client/tests/support/globalSetup.ts +++ b/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(); diff --git a/tests/e2e/project/commits.spec.ts b/tests/e2e/project/commits.spec.ts index 0ec7b3860..d448092cd 100644 --- a/tests/e2e/project/commits.spec.ts +++ b/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"); diff --git a/tests/e2e/project/issues.spec.ts b/tests/e2e/project/issues.spec.ts index 3956b0b87..2ae8ad4d9 100644 --- a/tests/e2e/project/issues.spec.ts +++ b/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"); diff --git a/tests/support/fixtures.ts b/tests/support/fixtures.ts index 0b6a6b001..a4db3fbd8 100644 --- a/tests/support/fixtures.ts +++ b/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: { diff --git a/tests/support/globalSetup.ts b/tests/support/globalSetup.ts index 053d02148..0facd9ba1 100644 --- a/tests/support/globalSetup.ts +++ b/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(); diff --git a/tests/support/peerManager.ts b/tests/support/peerManager.ts index 4549e2c1a..14f6f2032 100644 --- a/tests/support/peerManager.ts +++ b/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; #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 { + 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 {