mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-15 19:30:38 +08:00
Extract markdown from source-browsing fixture
Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { describe, test } from "vitest";
|
||||
|
||||
import { HttpdClient } from "../index";
|
||||
import { aliceMainHead, aliceRemote, rid } from "@tests/support/fixtures";
|
||||
import {
|
||||
aliceMainHead,
|
||||
aliceRemote,
|
||||
sourceBrowsingRid,
|
||||
} from "@tests/support/fixtures";
|
||||
|
||||
const api = new HttpdClient({
|
||||
hostname: "127.0.0.1",
|
||||
@@ -19,44 +23,47 @@ describe("project", () => {
|
||||
});
|
||||
|
||||
test("#getById(id)", async () => {
|
||||
await api.project.getById(rid);
|
||||
await api.project.getById(sourceBrowsingRid);
|
||||
});
|
||||
|
||||
test("#getActivity(id)", async () => {
|
||||
await api.project.getActivity(rid);
|
||||
await api.project.getActivity(sourceBrowsingRid);
|
||||
});
|
||||
|
||||
test("#getReadme(id, sha)", async () => {
|
||||
await api.project.getReadme(rid, aliceMainHead);
|
||||
await api.project.getReadme(sourceBrowsingRid, aliceMainHead);
|
||||
});
|
||||
|
||||
test("#getBlob(id, sha, path)", async () => {
|
||||
await api.project.getBlob(rid, aliceMainHead, "src/true.c");
|
||||
await api.project.getBlob(sourceBrowsingRid, aliceMainHead, "src/true.c");
|
||||
});
|
||||
|
||||
test("#getTree(id, sha)", async () => {
|
||||
await api.project.getTree(rid, aliceMainHead);
|
||||
await api.project.getTree(sourceBrowsingRid, aliceMainHead);
|
||||
});
|
||||
|
||||
test("#getTree(id, sha, path)", async () => {
|
||||
await api.project.getTree(rid, aliceMainHead, "src");
|
||||
await api.project.getTree(sourceBrowsingRid, aliceMainHead, "src");
|
||||
});
|
||||
|
||||
test("#getAllRemotes(id)", async () => {
|
||||
await api.project.getAllRemotes(rid);
|
||||
await api.project.getAllRemotes(sourceBrowsingRid);
|
||||
});
|
||||
|
||||
test("#getRemoteByPeer(id, peer)", async () => {
|
||||
await api.project.getRemoteByPeer(rid, aliceRemote.substring(8));
|
||||
await api.project.getRemoteByPeer(
|
||||
sourceBrowsingRid,
|
||||
aliceRemote.substring(8),
|
||||
);
|
||||
});
|
||||
|
||||
test("#getAllCommits(id)", async () => {
|
||||
await api.project.getAllCommits(rid);
|
||||
await api.project.getAllCommits(sourceBrowsingRid);
|
||||
});
|
||||
|
||||
// TODO: test since/until properly.
|
||||
test("#getAllCommits(id, {parent, since, until, page, perPage})", async () => {
|
||||
await api.project.getAllCommits(rid, {
|
||||
await api.project.getAllCommits(sourceBrowsingRid, {
|
||||
parent: aliceMainHead,
|
||||
since: 1679065819581,
|
||||
until: 1679065819590,
|
||||
@@ -66,7 +73,7 @@ describe("project", () => {
|
||||
});
|
||||
|
||||
test("#getCommitBySha(id, sha)", async () => {
|
||||
await api.project.getCommitBySha(rid, aliceMainHead);
|
||||
await api.project.getCommitBySha(sourceBrowsingRid, aliceMainHead);
|
||||
});
|
||||
|
||||
test.todo("#getDiff(id, revisionBase, revisionOid)");
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { Page } from "@playwright/test";
|
||||
|
||||
import {
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
rid,
|
||||
sourceBrowsingUrl,
|
||||
sourceBrowsingRid,
|
||||
seedRemote,
|
||||
test,
|
||||
} from "@tests/support/fixtures.js";
|
||||
@@ -26,7 +26,7 @@ test("copy to clipboard", async ({ page, browserName, context }) => {
|
||||
}
|
||||
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
|
||||
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
// Reset system clipboard to a known state.
|
||||
await page.evaluate<string>("navigator.clipboard.writeText('')");
|
||||
@@ -37,19 +37,21 @@ test("copy to clipboard", async ({ page, browserName, context }) => {
|
||||
const clipboardContent = await page.evaluate<string>(
|
||||
"navigator.clipboard.readText()",
|
||||
);
|
||||
expect(clipboardContent).toBe(rid);
|
||||
expect(clipboardContent).toBe(sourceBrowsingRid);
|
||||
}
|
||||
|
||||
// `rad clone` URL.
|
||||
{
|
||||
await page.getByText("Clone").click();
|
||||
await page.locator(`text=rad clone ${rid.substring(0, 6)}`).hover();
|
||||
await page
|
||||
.locator(`text=rad clone ${sourceBrowsingRid.substring(0, 6)}`)
|
||||
.hover();
|
||||
await page
|
||||
.locator(".clone-url-wrapper > span")
|
||||
.first()
|
||||
.locator(".clipboard")
|
||||
.click();
|
||||
await expectClipboard(`rad clone ${rid}`, page);
|
||||
await expectClipboard(`rad clone ${sourceBrowsingRid}`, page);
|
||||
}
|
||||
|
||||
// `git clone` URL.
|
||||
@@ -57,7 +59,7 @@ test("copy to clipboard", async ({ page, browserName, context }) => {
|
||||
await page.getByText("Clone").click();
|
||||
await page
|
||||
.locator(
|
||||
`text=git clone http://127.0.0.1/${rid
|
||||
`text=git clone http://127.0.0.1/${sourceBrowsingRid
|
||||
.replace("rad:", "")
|
||||
.substring(0, 10)}`,
|
||||
)
|
||||
@@ -68,7 +70,7 @@ test("copy to clipboard", async ({ page, browserName, context }) => {
|
||||
.locator(".clipboard")
|
||||
.click();
|
||||
await expectClipboard(
|
||||
`git clone http://127.0.0.1/${rid.replace(
|
||||
`git clone http://127.0.0.1/${sourceBrowsingRid.replace(
|
||||
"rad:",
|
||||
"",
|
||||
)}.git source-browsing`,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
aliceRemote,
|
||||
appConfigWithFixture,
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
sourceBrowsingUrl,
|
||||
test,
|
||||
} from "@tests/support/fixtures.js";
|
||||
import {
|
||||
@@ -18,7 +18,7 @@ test("navigate between landing and project page", async ({ page }) => {
|
||||
await expect(page).toHaveURL("/#/");
|
||||
|
||||
await page.locator("text=source-browsing").click();
|
||||
await expect(page).toHaveURL(`/#${projectFixtureUrl}`);
|
||||
await expect(page).toHaveURL(`/#${sourceBrowsingUrl}`);
|
||||
|
||||
await expectBackAndForwardNavigationWorks("/#/", page);
|
||||
await expectUrlPersistsReload(page);
|
||||
@@ -27,9 +27,9 @@ test("navigate between landing and project page", async ({ page }) => {
|
||||
test("navigation between seed and project pages", async ({ page }) => {
|
||||
await page.goto("/#/seeds/radicle.local");
|
||||
|
||||
const project = page.locator(".project");
|
||||
const project = page.locator(".project", { hasText: "source-browsing" });
|
||||
await project.click();
|
||||
await expect(page).toHaveURL(`/#${projectFixtureUrl}`);
|
||||
await expect(page).toHaveURL(`/#${sourceBrowsingUrl}`);
|
||||
|
||||
await expectBackAndForwardNavigationWorks("/#/seeds/radicle.local", page);
|
||||
await expectUrlPersistsReload(page);
|
||||
@@ -42,12 +42,12 @@ test.describe("project page navigation", () => {
|
||||
test("navigation between commit history and single commit", async ({
|
||||
page,
|
||||
}) => {
|
||||
const projectHistoryURL = `/#${projectFixtureUrl}/history/${aliceMainHead}`;
|
||||
const projectHistoryURL = `/#${sourceBrowsingUrl}/history/${aliceMainHead}`;
|
||||
await page.goto(projectHistoryURL);
|
||||
|
||||
await page.locator("text=Add Markdown cheat sheet").click();
|
||||
await page.locator("text=Add README.md").click();
|
||||
await expect(page).toHaveURL(
|
||||
`/#${projectFixtureUrl}/commits/f0b8db68847b01f0964380507a9db6800e5b5342`,
|
||||
`/#${sourceBrowsingUrl}/commits/${aliceMainHead}`,
|
||||
);
|
||||
|
||||
await expectBackAndForwardNavigationWorks(projectHistoryURL, page);
|
||||
@@ -55,20 +55,20 @@ test.describe("project page navigation", () => {
|
||||
});
|
||||
|
||||
test("navigate between tree and commit history", async ({ page }) => {
|
||||
const projectTreeURL = `/#${projectFixtureUrl}`;
|
||||
const projectTreeURL = `/#${sourceBrowsingUrl}`;
|
||||
|
||||
await page.goto(projectTreeURL);
|
||||
await expect(page).toHaveURL(projectTreeURL);
|
||||
|
||||
await page.locator('role=link[name="8 commits"]').click();
|
||||
await expect(page).toHaveURL(`/#${projectFixtureUrl}/history`);
|
||||
await page.locator('role=link[name="6 commits"]').click();
|
||||
await expect(page).toHaveURL(`/#${sourceBrowsingUrl}/history`);
|
||||
|
||||
await expectBackAndForwardNavigationWorks(projectTreeURL, page);
|
||||
await expectUrlPersistsReload(page);
|
||||
});
|
||||
|
||||
test("navigate project paths", async ({ page }) => {
|
||||
const projectTreeURL = `/#${projectFixtureUrl}`;
|
||||
const projectTreeURL = `/#${sourceBrowsingUrl}`;
|
||||
|
||||
await page.goto(projectTreeURL);
|
||||
await expect(page).toHaveURL(projectTreeURL);
|
||||
@@ -88,7 +88,7 @@ test.describe("project page navigation", () => {
|
||||
});
|
||||
|
||||
test("navigate project paths with a selected peer", async ({ page }) => {
|
||||
const projectTreeURL = `/#${projectFixtureUrl}/remotes/${aliceRemote.substring(
|
||||
const projectTreeURL = `/#${sourceBrowsingUrl}/remotes/${aliceRemote.substring(
|
||||
8,
|
||||
)}`;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
aliceRemote,
|
||||
appConfigWithFixture,
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
sourceBrowsingUrl,
|
||||
test,
|
||||
} from "@tests/support/fixtures.js";
|
||||
import {
|
||||
@@ -18,7 +18,7 @@ test("navigate between landing and project page", async ({ page }) => {
|
||||
await expect(page).toHaveURL("/");
|
||||
|
||||
await page.locator("text=source-browsing").click();
|
||||
await expect(page).toHaveURL(projectFixtureUrl);
|
||||
await expect(page).toHaveURL(sourceBrowsingUrl);
|
||||
|
||||
await expectBackAndForwardNavigationWorks("/", page);
|
||||
await expectUrlPersistsReload(page);
|
||||
@@ -27,9 +27,9 @@ test("navigate between landing and project page", async ({ page }) => {
|
||||
test("navigation between seed and project pages", async ({ page }) => {
|
||||
await page.goto("/seeds/radicle.local");
|
||||
|
||||
const project = page.locator(".project");
|
||||
const project = page.locator(".project", { hasText: "source-browsing" });
|
||||
await project.click();
|
||||
await expect(page).toHaveURL(projectFixtureUrl);
|
||||
await expect(page).toHaveURL(sourceBrowsingUrl);
|
||||
|
||||
await expectBackAndForwardNavigationWorks("/seeds/radicle.local", page);
|
||||
await expectUrlPersistsReload(page);
|
||||
@@ -42,12 +42,12 @@ test.describe("project page navigation", () => {
|
||||
test("navigation between commit history and single commit", async ({
|
||||
page,
|
||||
}) => {
|
||||
const projectHistoryURL = `${projectFixtureUrl}/history/${aliceMainHead}`;
|
||||
const projectHistoryURL = `${sourceBrowsingUrl}/history/${aliceMainHead}`;
|
||||
await page.goto(projectHistoryURL);
|
||||
|
||||
await page.locator("text=Add Markdown cheat sheet").click();
|
||||
await page.locator("text=Add README.md").click();
|
||||
await expect(page).toHaveURL(
|
||||
`${projectFixtureUrl}/commits/f0b8db68847b01f0964380507a9db6800e5b5342`,
|
||||
`${sourceBrowsingUrl}/commits/${aliceMainHead}`,
|
||||
);
|
||||
|
||||
await expectBackAndForwardNavigationWorks(projectHistoryURL, page);
|
||||
@@ -55,14 +55,14 @@ test.describe("project page navigation", () => {
|
||||
});
|
||||
|
||||
test("navigate between tree and commit history", async ({ page }) => {
|
||||
const projectTreeURL = `${projectFixtureUrl}/tree/${aliceMainHead}`;
|
||||
const projectTreeURL = `${sourceBrowsingUrl}/tree/${aliceMainHead}`;
|
||||
|
||||
await page.goto(projectTreeURL);
|
||||
await expect(page).toHaveURL(projectTreeURL);
|
||||
|
||||
await page.locator('role=link[name="8 commits"]').click();
|
||||
await page.locator('role=link[name="6 commits"]').click();
|
||||
await expect(page).toHaveURL(
|
||||
`${projectFixtureUrl}/history/${aliceMainHead}`,
|
||||
`${sourceBrowsingUrl}/history/${aliceMainHead}`,
|
||||
);
|
||||
|
||||
await expectBackAndForwardNavigationWorks(projectTreeURL, page);
|
||||
@@ -70,7 +70,7 @@ test.describe("project page navigation", () => {
|
||||
});
|
||||
|
||||
test("navigate project paths", async ({ page }) => {
|
||||
const projectTreeURL = `${projectFixtureUrl}/tree/${aliceMainHead}`;
|
||||
const projectTreeURL = `${sourceBrowsingUrl}/tree/${aliceMainHead}`;
|
||||
|
||||
await page.goto(projectTreeURL);
|
||||
await expect(page).toHaveURL(projectTreeURL);
|
||||
@@ -90,7 +90,7 @@ test.describe("project page navigation", () => {
|
||||
});
|
||||
|
||||
test("navigate project paths with a selected peer", async ({ page }) => {
|
||||
const projectTreeURL = `${projectFixtureUrl}/remotes/${aliceRemote.substring(
|
||||
const projectTreeURL = `${sourceBrowsingUrl}/remotes/${aliceRemote.substring(
|
||||
8,
|
||||
)}`;
|
||||
|
||||
|
||||
+49
-47
@@ -3,10 +3,12 @@ import type { Page } from "@playwright/test";
|
||||
import {
|
||||
aliceMainHead,
|
||||
aliceRemote,
|
||||
bobHead,
|
||||
bobRemote,
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
rid,
|
||||
markdownUrl,
|
||||
sourceBrowsingRid,
|
||||
sourceBrowsingUrl,
|
||||
test,
|
||||
} from "@tests/support/fixtures.js";
|
||||
import { expectUrlPersistsReload } from "@tests/support/router";
|
||||
@@ -33,12 +35,12 @@ async function expectCounts(
|
||||
}
|
||||
|
||||
test("navigate to project", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
// Header.
|
||||
{
|
||||
const name = page.locator("text=source-browsing");
|
||||
const id = page.locator(`text=${rid}`);
|
||||
const id = page.locator(`text=${sourceBrowsingRid}`);
|
||||
const description = page.locator(
|
||||
"text=Git repository for source browsing tests",
|
||||
);
|
||||
@@ -53,7 +55,7 @@ test("navigate to project", async ({ page }) => {
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
`main ${aliceMainHead.substring(0, 7)}`,
|
||||
);
|
||||
await expectCounts({ commits: 8, contributors: 1 }, page);
|
||||
await expectCounts({ commits: 6, contributors: 1 }, page);
|
||||
}
|
||||
|
||||
// Navigate to the project README.md by default.
|
||||
@@ -70,8 +72,8 @@ test("navigate to project", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("show source tree at specific revision", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.locator('role=link[name="8 commits"]').click();
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
await page.locator('role=link[name="6 commits"]').click();
|
||||
|
||||
await page
|
||||
.locator(".teaser", { hasText: "335dd6d" })
|
||||
@@ -86,7 +88,7 @@ test("show source tree at specific revision", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("source file highlighting", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
await page.getByText("src/").click();
|
||||
await page.getByText("true.c").click();
|
||||
@@ -98,14 +100,12 @@ test("source file highlighting", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("navigate line numbers", async ({ page }) => {
|
||||
await page.goto(`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md`);
|
||||
await page.goto(`${markdownUrl}/tree/main/cheatsheet.md`);
|
||||
await page.locator('text="Plain"').click();
|
||||
|
||||
await page.locator('[href="#L5"]').click();
|
||||
await expect(page.locator("#L5")).toHaveClass("line highlight");
|
||||
await expect(page).toHaveURL(
|
||||
`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md#L5`,
|
||||
);
|
||||
await expect(page).toHaveURL(`${markdownUrl}/tree/main/cheatsheet.md#L5`);
|
||||
|
||||
await expectUrlPersistsReload(page);
|
||||
await expect(page.locator("#L5")).toHaveClass("line highlight");
|
||||
@@ -113,16 +113,11 @@ test("navigate line numbers", async ({ page }) => {
|
||||
await page.locator('[href="#L30"]').click();
|
||||
await expect(page.locator("#L5")).not.toHaveClass("line highlight");
|
||||
await expect(page.locator("#L30")).toHaveClass("line highlight");
|
||||
await expect(page).toHaveURL(
|
||||
`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md#L30`,
|
||||
);
|
||||
|
||||
await page.getByText(".hidden").click();
|
||||
await expect(page).toHaveURL(`${projectFixtureUrl}/tree/main/.hidden`);
|
||||
await expect(page).toHaveURL(`${markdownUrl}/tree/main/cheatsheet.md#L30`);
|
||||
});
|
||||
|
||||
test("navigate deep file hierarchies", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
const sourceTree = page.locator(".source-tree");
|
||||
|
||||
@@ -165,7 +160,7 @@ test("navigate deep file hierarchies", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("files with special characters in the filename", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
const sourceTree = page.locator(".source-tree");
|
||||
await sourceTree.getByText("special/").click();
|
||||
@@ -209,7 +204,7 @@ test("files with special characters in the filename", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("binary files", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
await page.getByText("bin/").click();
|
||||
await page.getByText("true").click();
|
||||
@@ -218,7 +213,7 @@ test("binary files", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("hidden files", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
await page.getByText(".hidden").click();
|
||||
|
||||
@@ -226,7 +221,7 @@ test("hidden files", async ({ page }) => {
|
||||
});
|
||||
|
||||
test("markdown files", async ({ page }) => {
|
||||
await page.goto(`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md`);
|
||||
await page.goto(`${markdownUrl}/tree/main/cheatsheet.md`);
|
||||
|
||||
await expect(
|
||||
page.locator("text=This is intended as a quick reference and showcase."),
|
||||
@@ -246,23 +241,27 @@ test("markdown files", async ({ page }) => {
|
||||
{
|
||||
await page.getByRole("link", { name: "YouTube Videos" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md#videos`,
|
||||
`${markdownUrl}/tree/main/cheatsheet.md#videos`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("clone modal", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
await page.getByText("Clone").click();
|
||||
await expect(page.locator(`text=rad clone ${rid}`)).toBeVisible();
|
||||
await expect(
|
||||
page.locator(`text=http://127.0.0.1/${rid.replace("rad:", "")}.git`),
|
||||
page.locator(`text=rad clone ${sourceBrowsingRid}`),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator(
|
||||
`text=http://127.0.0.1/${sourceBrowsingRid.replace("rad:", "")}.git`,
|
||||
),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("peer and branch switching", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
// Alice's peer.
|
||||
{
|
||||
@@ -284,9 +283,9 @@ test("peer and branch switching", async ({ page }) => {
|
||||
// Default `main` branch.
|
||||
{
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
"main fcc9294",
|
||||
`main ${aliceMainHead.substring(0, 7)}`,
|
||||
);
|
||||
await expectCounts({ commits: 8, contributors: 1 }, page);
|
||||
await expectCounts({ commits: 6, contributors: 1 }, page);
|
||||
}
|
||||
|
||||
// Feature branch with a slash in the name.
|
||||
@@ -295,9 +294,9 @@ test("peer and branch switching", async ({ page }) => {
|
||||
await page.locator("text=feature/branch").click();
|
||||
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
"feature/branch d6318f7",
|
||||
"feature/branch 1aded56",
|
||||
);
|
||||
await expectCounts({ commits: 10, contributors: 1 }, page);
|
||||
await expectCounts({ commits: 9, contributors: 1 }, page);
|
||||
}
|
||||
|
||||
// Branch without a history or files in it.
|
||||
@@ -324,7 +323,7 @@ test("peer and branch switching", async ({ page }) => {
|
||||
await expect(page.getByTitle("Change peer")).not.toContainText("bob");
|
||||
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
"main fcc9294",
|
||||
`main ${aliceMainHead.substring(0, 7)}`,
|
||||
);
|
||||
await expect(page.locator("text=Git test repository")).toBeVisible();
|
||||
}
|
||||
@@ -343,16 +342,18 @@ test("peer and branch switching", async ({ page }) => {
|
||||
// Default `main` branch.
|
||||
{
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
"main ec5eb0b",
|
||||
`main ${bobHead.substring(0, 7)}`,
|
||||
);
|
||||
await expectCounts({ commits: 9, contributors: 2 }, page);
|
||||
await expect(page.locator("text=ec5eb0b Update readme")).toBeVisible();
|
||||
await expectCounts({ commits: 7, contributors: 2 }, page);
|
||||
await expect(
|
||||
page.locator(`text=${bobHead.substring(0, 7)} Update readme`),
|
||||
).toBeVisible();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("only one modal can be open at a time", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
await page.getByTitle("Change peer").click();
|
||||
await page.locator(`text=${aliceRemote}`).click();
|
||||
@@ -385,14 +386,14 @@ test("only one modal can be open at a time", async ({ page }) => {
|
||||
test.describe("browser error handling", () => {
|
||||
test("error appears when folder can't be loaded", async ({ page }) => {
|
||||
await page.route(
|
||||
`**/v1/projects/${rid}/tree/${aliceMainHead}/markdown/`,
|
||||
`**/v1/projects/${sourceBrowsingRid}/tree/${aliceMainHead}/src/`,
|
||||
route => route.fulfill({ status: 500 }),
|
||||
);
|
||||
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
|
||||
const sourceTree = page.locator(".source-tree");
|
||||
await sourceTree.locator("text=markdown/").click();
|
||||
await sourceTree.locator("text=src/").click();
|
||||
|
||||
await expect(
|
||||
page.locator("text=Not able to expand directory"),
|
||||
@@ -400,32 +401,33 @@ test.describe("browser error handling", () => {
|
||||
});
|
||||
test("error appears when file can't be loaded", async ({ page }) => {
|
||||
await page.route(
|
||||
`**/v1/projects/${rid}/blob/${aliceMainHead}/.hidden`,
|
||||
`**/v1/projects/${sourceBrowsingRid}/blob/${aliceMainHead}/.hidden`,
|
||||
route => route.fulfill({ status: 500 }),
|
||||
);
|
||||
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
await page.locator("text=.hidden").click();
|
||||
|
||||
await expect(page.locator("text=Not able to load file")).toBeVisible();
|
||||
});
|
||||
test("error appears when README can't be loaded", async ({ page }) => {
|
||||
await page.route(`**/v1/projects/${rid}/readme/${aliceMainHead}`, route =>
|
||||
route.fulfill({ status: 500 }),
|
||||
await page.route(
|
||||
`**/v1/projects/${sourceBrowsingRid}/readme/${aliceMainHead}`,
|
||||
route => route.fulfill({ status: 500 }),
|
||||
);
|
||||
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
await expect(
|
||||
page.locator("text=The README could not be loaded."),
|
||||
).toBeVisible();
|
||||
});
|
||||
test("error appears when navigating to missing file", async ({ page }) => {
|
||||
await page.route(
|
||||
`**/v1/projects/${rid}/blob/${aliceMainHead}/.hidden`,
|
||||
`**/v1/projects/${sourceBrowsingRid}/blob/${aliceMainHead}/.hidden`,
|
||||
route => route.fulfill({ status: 500 }),
|
||||
);
|
||||
|
||||
await page.goto(`${projectFixtureUrl}/tree/master/.hidden`);
|
||||
await page.goto(`${sourceBrowsingUrl}/tree/master/.hidden`);
|
||||
|
||||
await expect(page.locator("text=Not able to load file")).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
sourceBrowsingUrl,
|
||||
bobRemote,
|
||||
bobHead,
|
||||
aliceRemote,
|
||||
} from "@tests/support/fixtures.js";
|
||||
|
||||
const modifiedFileFixture = `${projectFixtureUrl}/remotes/${bobRemote.substring(
|
||||
const modifiedFileFixture = `${sourceBrowsingUrl}/remotes/${bobRemote.substring(
|
||||
8,
|
||||
)}/commits/${bobHead}`;
|
||||
|
||||
test("navigation from commit list", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
await page.getByTitle("Change peer").click();
|
||||
await page.locator(`text=${bobRemote}`).click();
|
||||
await page.locator('role=link[name="9 commits"]').click();
|
||||
await page.locator('role=link[name="7 commits"]').click();
|
||||
|
||||
await page.locator("text=Update readme").click();
|
||||
await expect(page).toHaveURL(modifiedFileFixture);
|
||||
@@ -43,9 +44,7 @@ test("modified file", async ({ page }) => {
|
||||
{
|
||||
const header = page.locator(".commit .header");
|
||||
await expect(header.locator("text=Update readme")).toBeVisible();
|
||||
await expect(
|
||||
header.locator("text=ec5eb0b5efb73da17a2d25454cc47eea3967f328"),
|
||||
).toBeVisible();
|
||||
await expect(header.locator(`text=${bobHead}`)).toBeVisible();
|
||||
}
|
||||
|
||||
// Diff header.
|
||||
@@ -60,17 +59,21 @@ test("modified file", async ({ page }) => {
|
||||
|
||||
test("created file", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${projectFixtureUrl}/remotes/${bobRemote}/commits/d6318f7f3d9c15b8ac6dd52267c53220d00f0982`,
|
||||
`${sourceBrowsingUrl}/remotes/${aliceRemote.substring(
|
||||
8,
|
||||
)}/commits/d87e27e38e244fb3346cb9e4df064c080d97647a`,
|
||||
);
|
||||
await expect(
|
||||
page.locator("text=1 file added with 9 insertions and 0 deletions"),
|
||||
page.locator("text=1 file added with 1 insertion and 0 deletions"),
|
||||
).toBeVisible();
|
||||
await expect(page.locator("text=subconscious.txt added")).toBeVisible();
|
||||
await expect(page.locator("text=.hidden added")).toBeVisible();
|
||||
});
|
||||
|
||||
test("deleted file", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${projectFixtureUrl}/remotes/${bobRemote}/commits/cd13c2d9a8a930d64a82b6134b44d1b872e33662`,
|
||||
`${sourceBrowsingUrl}/remotes/${aliceRemote.substring(
|
||||
8,
|
||||
)}/commits/0e2db54dfd47d87202809917e2342655d9e76296`,
|
||||
);
|
||||
await expect(
|
||||
page.locator("text=1 file deleted with 0 insertions and 1 deletion"),
|
||||
@@ -80,7 +83,7 @@ test("deleted file", async ({ page }) => {
|
||||
|
||||
test("navigation to source tree at specific revision", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${projectFixtureUrl}/commits/0801aceeab500033f8d608778218657bd626ef73`,
|
||||
`${sourceBrowsingUrl}/commits/0801aceeab500033f8d608778218657bd626ef73`,
|
||||
);
|
||||
|
||||
// Go to source tree at this revision.
|
||||
@@ -89,7 +92,7 @@ test("navigation to source tree at specific revision", async ({ page }) => {
|
||||
page.locator("text=Add a deeply nested directory tree"),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveURL(
|
||||
`${projectFixtureUrl}/tree/0801aceeab500033f8d608778218657bd626ef73/deep/directory/hierarchy/is/entirely/possible/in/git/repositories/.gitkeep`,
|
||||
`${sourceBrowsingUrl}/tree/0801aceeab500033f8d608778218657bd626ef73/deep/directory/hierarchy/is/entirely/possible/in/git/repositories/.gitkeep`,
|
||||
);
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
"0801aceeab500033f8d608778218657bd626ef73",
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
sourceBrowsingUrl,
|
||||
bobRemote,
|
||||
aliceRemote,
|
||||
gitOptions,
|
||||
aliceMainHead,
|
||||
} from "@tests/support/fixtures.js";
|
||||
import { createProject } from "@tests/support/project";
|
||||
|
||||
test("peer and branch switching", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.locator('role=link[name="8 commits"]').click();
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
await page.locator('role=link[name="6 commits"]').click();
|
||||
|
||||
// Alice's peer.
|
||||
{
|
||||
@@ -22,13 +24,11 @@ test("peer and branch switching", async ({ page }) => {
|
||||
);
|
||||
|
||||
await expect(page.getByText("Thursday, November 17, 2022")).toBeVisible();
|
||||
await expect(page.locator(".history .teaser")).toHaveCount(8);
|
||||
await expect(page.locator(".history .teaser")).toHaveCount(6);
|
||||
|
||||
const latestCommit = page.locator(".teaser").first();
|
||||
await expect(latestCommit).toContainText(
|
||||
"Adds a new markdown file with an image with a relative path",
|
||||
);
|
||||
await expect(latestCommit).toContainText("fcc9294");
|
||||
await expect(latestCommit).toContainText("Add README.md");
|
||||
await expect(latestCommit).toContainText(aliceMainHead.substring(0, 7));
|
||||
|
||||
const earliestCommit = page.locator(".teaser").last();
|
||||
await expect(earliestCommit).toContainText(
|
||||
@@ -40,10 +40,10 @@ test("peer and branch switching", async ({ page }) => {
|
||||
await page.locator("text=feature/branch").click();
|
||||
|
||||
await expect(page.getByTitle("Current branch")).toContainText(
|
||||
"feature/branch d6318f7",
|
||||
"feature/branch 1aded56",
|
||||
);
|
||||
await expect(page.getByText("Thursday, November 17, 2022")).toBeVisible();
|
||||
await expect(page.locator(".history .teaser")).toHaveCount(10);
|
||||
await expect(page.locator(".history .teaser")).toHaveCount(9);
|
||||
|
||||
await page.getByTitle("Change branch").click();
|
||||
await page.locator("text=orphaned-branch").click();
|
||||
@@ -65,7 +65,7 @@ test("peer and branch switching", async ({ page }) => {
|
||||
)} `,
|
||||
);
|
||||
|
||||
await expect(page.getByText("Tuesday, December 20, 2022")).toBeVisible();
|
||||
await expect(page.getByText("Wednesday, December 21, 2022")).toBeVisible();
|
||||
await expect(page.locator(".group").first().locator(".teaser")).toHaveCount(
|
||||
1,
|
||||
);
|
||||
@@ -77,7 +77,7 @@ test("peer and branch switching", async ({ page }) => {
|
||||
|
||||
const latestCommit = page.locator(".teaser").first();
|
||||
await expect(latestCommit).toContainText("Update readme");
|
||||
await expect(latestCommit).toContainText("ec5eb0b");
|
||||
await expect(latestCommit).toContainText("28f3710");
|
||||
|
||||
const earliestCommit = page.locator(".teaser").last();
|
||||
await expect(earliestCommit).toContainText(
|
||||
@@ -98,8 +98,8 @@ test("relative timestamps", async ({ page }) => {
|
||||
};
|
||||
});
|
||||
|
||||
await page.goto(projectFixtureUrl);
|
||||
await page.locator('role=link[name="8 commits"]').click();
|
||||
await page.goto(sourceBrowsingUrl);
|
||||
await page.locator('role=link[name="6 commits"]').click();
|
||||
|
||||
await page.getByTitle("Change peer").click();
|
||||
await page.locator(`text=${bobRemote}`).click();
|
||||
@@ -110,7 +110,7 @@ test("relative timestamps", async ({ page }) => {
|
||||
);
|
||||
const latestCommit = page.locator(".teaser").first();
|
||||
await expect(latestCommit).toContainText("Bob Belcher committed now");
|
||||
await expect(latestCommit).toContainText("ec5eb0b");
|
||||
await expect(latestCommit).toContainText("28f3710");
|
||||
const earliestCommit = page.locator(".teaser").last();
|
||||
await expect(earliestCommit).toContainText(
|
||||
"Alice Liddell committed last month",
|
||||
@@ -124,7 +124,7 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
|
||||
});
|
||||
await alice.startHttpd(8090);
|
||||
await alice.startNode();
|
||||
const { rid, projectFolder } = await alice.createProject("alice-project");
|
||||
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`);
|
||||
|
||||
@@ -2,19 +2,19 @@ import { searchPlaceholder } from "@app/lib/shared";
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
rid,
|
||||
projectFixtureUrl,
|
||||
sourceBrowsingRid,
|
||||
sourceBrowsingUrl,
|
||||
} from "@tests/support/fixtures.js";
|
||||
|
||||
test("navigate to existing project", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
const searchInput = page.getByPlaceholder(searchPlaceholder);
|
||||
await searchInput.click();
|
||||
await searchInput.fill(`${rid}`);
|
||||
await searchInput.fill(sourceBrowsingRid);
|
||||
await searchInput.press("Enter");
|
||||
|
||||
await expect(page).toHaveURL(projectFixtureUrl);
|
||||
await expect(searchInput).not.toHaveValue(`${rid}`);
|
||||
await expect(page).toHaveURL(sourceBrowsingUrl);
|
||||
await expect(searchInput).not.toHaveValue(sourceBrowsingRid);
|
||||
});
|
||||
|
||||
test("navigate to a project that does not exist", async ({ page }) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
aliceMainHead,
|
||||
expect,
|
||||
rid,
|
||||
sourceBrowsingRid,
|
||||
seedRemote,
|
||||
test,
|
||||
} from "@tests/support/fixtures.js";
|
||||
@@ -20,7 +20,7 @@ test("seed metadata", async ({ page }) => {
|
||||
|
||||
test("seed projects", async ({ page }) => {
|
||||
await page.goto("/seeds/radicle.local");
|
||||
const project = page.locator(".project");
|
||||
const project = page.locator(".project", { hasText: "source-browsing" });
|
||||
|
||||
// Project metadata.
|
||||
{
|
||||
@@ -33,8 +33,10 @@ test("seed projects", async ({ page }) => {
|
||||
|
||||
// Show project ID on hover.
|
||||
{
|
||||
await expect(project.locator(`text=${rid}`)).not.toBeVisible();
|
||||
await expect(
|
||||
project.locator(`text=${sourceBrowsingRid}`),
|
||||
).not.toBeVisible();
|
||||
await project.hover();
|
||||
await expect(project.locator(`text=${rid}`)).toBeVisible();
|
||||
await expect(project.locator(`text=${sourceBrowsingRid}`)).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect, projectFixtureUrl } from "@tests/support/fixtures.js";
|
||||
import { test, expect, sourceBrowsingUrl } from "@tests/support/fixtures.js";
|
||||
|
||||
const sourceBrowsingFixture = `${projectFixtureUrl}/tree/main/src/true.c`;
|
||||
const sourceBrowsingFixture = `${sourceBrowsingUrl}/tree/main/src/true.c`;
|
||||
|
||||
test("default settings", async ({ page }) => {
|
||||
await page.goto(sourceBrowsingFixture);
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+44
-23
@@ -1,24 +1,25 @@
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import type * as Stream from "node:stream";
|
||||
import type { PeerManager } from "./peerManager.js";
|
||||
import type { PeerManager, RadiclePeer } from "./peerManager.js";
|
||||
|
||||
import * as Fs from "node:fs/promises";
|
||||
import * as FsSync from "node:fs";
|
||||
import * as Path from "node:path";
|
||||
import { dirname } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { test as base, expect } from "@playwright/test";
|
||||
|
||||
import * as Process from "./process.js";
|
||||
import * as logLabel from "@tests/support/logLabel.js";
|
||||
import { createPeerManager } from "./peerManager.js";
|
||||
import { createPeerManager } from "@tests/support/peerManager.js";
|
||||
import { createProject } from "@tests/support/project.js";
|
||||
|
||||
export { expect };
|
||||
|
||||
const filename = fileURLToPath(import.meta.url);
|
||||
export const supportDir = dirname(filename);
|
||||
export const tmpDir = Path.resolve(supportDir, "..", "./tmp");
|
||||
const fixturesDir = Path.resolve(supportDir, "..", "./fixtures");
|
||||
export const fixturesDir = Path.resolve(supportDir, "..", "./fixtures");
|
||||
|
||||
export const test = base.extend<{
|
||||
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
||||
@@ -206,10 +207,13 @@ export async function startPalmHttpd() {
|
||||
outputLog: FsSync.createWriteStream(Path.resolve(Path.join(tmpDir, "log"))),
|
||||
});
|
||||
const palm = await peerManager.startPeer({ name: "palm" });
|
||||
await palm.startHttpd();
|
||||
await palm.startHttpd(8080);
|
||||
}
|
||||
|
||||
export async function createSeedFixture() {
|
||||
export async function createSourceBrowsingFixture(
|
||||
peerManager: PeerManager,
|
||||
palm: RadiclePeer,
|
||||
) {
|
||||
const projectName = "source-browsing";
|
||||
const sourceBrowsingDir = Path.join(tmpDir, "repos", projectName);
|
||||
await Fs.mkdir(sourceBrowsingDir, { recursive: true });
|
||||
@@ -219,17 +223,7 @@ export async function createSeedFixture() {
|
||||
"-C",
|
||||
sourceBrowsingDir,
|
||||
]);
|
||||
// Workaround for fixing MaxListenersExceededWarning.
|
||||
// Since every prefixOutput stream adds stream listeners that don't autoClose.
|
||||
// TODO: We still seem to have some descriptors left open when running vitest, which we should handle.
|
||||
const peerManager = await createPeerManager({
|
||||
dataDir: Path.resolve(Path.join(tmpDir, "peers")),
|
||||
outputLog: FsSync.createWriteStream(
|
||||
Path.join(tmpDir, "log"),
|
||||
).setMaxListeners(20),
|
||||
});
|
||||
const palm = await peerManager.startPeer({ name: "palm" });
|
||||
await palm.startHttpd();
|
||||
const rid = sourceBrowsingRid;
|
||||
const alice = await peerManager.startPeer({
|
||||
name: "alice",
|
||||
gitOptions: gitOptions["alice"],
|
||||
@@ -240,7 +234,6 @@ export async function createSeedFixture() {
|
||||
gitOptions: gitOptions["bob"],
|
||||
});
|
||||
const bobProjectPath = Path.join(bob.checkoutPath, "source-browsing");
|
||||
await palm.startNode({ trackingPolicy: "track", trackingScope: "all" });
|
||||
await alice.startNode();
|
||||
await bob.startNode();
|
||||
await alice.connect(palm);
|
||||
@@ -304,14 +297,42 @@ export async function createSeedFixture() {
|
||||
);
|
||||
}
|
||||
|
||||
export const aliceMainHead = "fcc929424b82984b7cbff9c01d2e20d9b1249842";
|
||||
export async function createMarkdownFixture(peer: RadiclePeer) {
|
||||
await Fs.mkdir(Path.join(tmpDir, "repos", "markdown"));
|
||||
await Process.spawn("tar", [
|
||||
"-xf",
|
||||
Path.join(fixturesDir, "repos", "markdown.tar.bz2"),
|
||||
"-C",
|
||||
Path.join(tmpDir, "repos", "markdown"),
|
||||
]);
|
||||
const { projectFolder } = await createProject(peer, "markdown");
|
||||
await Fs.cp(Path.join(tmpDir, "repos", "markdown"), projectFolder, {
|
||||
recursive: true,
|
||||
});
|
||||
|
||||
await peer.git(["add", "."], { cwd: projectFolder });
|
||||
const commitMessage = `Add Markdown cheat sheet
|
||||
|
||||
Borrowed from [Adam Pritchard][ap].
|
||||
No modifications were made.
|
||||
|
||||
[ap]: https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet`;
|
||||
await peer.git(["commit", "-m", commitMessage], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await peer.git(["push", "rad"], { cwd: projectFolder });
|
||||
}
|
||||
|
||||
export const aliceMainHead = "dd068e9aff9a569e597f6abaf84f120dd0cbbd70";
|
||||
export const aliceRemote =
|
||||
"did:key:z6MkqGC3nWZhYieEVTVDKW5v588CiGfsDSmRVG9ZwwWTvLSK";
|
||||
export const bobRemote =
|
||||
"did:key:z6Mkg49NtQR2LyYRDCQFK4w1VVHqhypZSSRo7HsyuN7SV7v5";
|
||||
export const bobHead = "ec5eb0b5efb73da17a2d25454cc47eea3967f328";
|
||||
export const rid = "rad:z4BwwjPCFNVP27FwVbDFgwVwkjcir";
|
||||
export const projectFixtureUrl = `/seeds/127.0.0.1/${rid}`;
|
||||
export const bobHead = "28f37105bb78db48111e36281291ff253dd050e8";
|
||||
export const sourceBrowsingRid = "rad:z4BwwjPCFNVP27FwVbDFgwVwkjcir";
|
||||
export const markdownRid = "rad:z2tchH2Ti4LxRKdssPQYs6VHE5rsg";
|
||||
export const sourceBrowsingUrl = `/seeds/127.0.0.1/${sourceBrowsingRid}`;
|
||||
export const markdownUrl = `/seeds/127.0.0.1/${markdownRid}`;
|
||||
export const seedPort = 8080;
|
||||
export const seedRemote = "z6MktULudTtAsAhRegYPiZ6631RV3viv12qd4GQF8z1xB22S";
|
||||
export const gitOptions = {
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import type { FullConfig } from "@playwright/test";
|
||||
|
||||
import * as Fs from "node:fs/promises";
|
||||
import * as FsSync from "node:fs";
|
||||
import * as Path from "node:path";
|
||||
import * as readline from "node:readline/promises";
|
||||
import { execa } from "execa";
|
||||
|
||||
import {
|
||||
createSeedFixture,
|
||||
supportDir,
|
||||
createMarkdownFixture,
|
||||
createSourceBrowsingFixture,
|
||||
gitOptions,
|
||||
startPalmHttpd,
|
||||
supportDir,
|
||||
tmpDir,
|
||||
} from "./fixtures.js";
|
||||
} from "@tests/support/fixtures.js";
|
||||
import { createPeerManager } from "@tests/support/peerManager.js";
|
||||
|
||||
const workspacePaths = [Path.join(tmpDir, "peers"), Path.join(tmpDir, "repos")];
|
||||
|
||||
@@ -33,8 +37,27 @@ export default async function globalSetup(_config: FullConfig): Promise<void> {
|
||||
}
|
||||
await removeWorkspace();
|
||||
|
||||
console.log("Creating seed fixture");
|
||||
await createSeedFixture();
|
||||
// Workaround for fixing MaxListenersExceededWarning.
|
||||
// Since every prefixOutput stream adds stream listeners that don't autoClose.
|
||||
// TODO: We still seem to have some descriptors left open when running vitest, which we should handle.
|
||||
const peerManager = await createPeerManager({
|
||||
dataDir: Path.resolve(Path.join(tmpDir, "peers")),
|
||||
outputLog: FsSync.createWriteStream(
|
||||
Path.join(tmpDir, "peerManager.log"),
|
||||
).setMaxListeners(20),
|
||||
});
|
||||
|
||||
const palm = await peerManager.startPeer({
|
||||
name: "palm",
|
||||
gitOptions: gitOptions["alice"],
|
||||
});
|
||||
await palm.startHttpd(8080);
|
||||
await palm.startNode({ trackingPolicy: "track", trackingScope: "all" });
|
||||
|
||||
console.log("Creating source-browsing fixture");
|
||||
await createSourceBrowsingFixture(peerManager, palm);
|
||||
console.log("Creating markdown fixture");
|
||||
await createMarkdownFixture(palm);
|
||||
console.log("Running tests");
|
||||
} else {
|
||||
await startPalmHttpd();
|
||||
|
||||
@@ -81,7 +81,7 @@ export async function createPeerManager(createParams: {
|
||||
outputLog = createParams.outputLog;
|
||||
} else {
|
||||
outputLogFile = await Fs.open(
|
||||
Path.join(createParams.dataDir, "peer-manager.log"),
|
||||
Path.join(createParams.dataDir, "peerManager.log"),
|
||||
"a",
|
||||
);
|
||||
outputLog = outputLogFile.createWriteStream();
|
||||
@@ -89,7 +89,6 @@ export async function createPeerManager(createParams: {
|
||||
|
||||
const nodes: RadiclePeer[] = [];
|
||||
return {
|
||||
// Starts a new node and registers it.
|
||||
async startPeer(params) {
|
||||
const peer = await RadiclePeer.create({
|
||||
dataPath: createParams.dataDir,
|
||||
@@ -183,9 +182,8 @@ export class RadiclePeer {
|
||||
});
|
||||
}
|
||||
|
||||
public async startHttpd(port = 8080) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.spawn("radicle-httpd", ["--listen", `0.0.0.0:${port}`]);
|
||||
public async startHttpd(port: number) {
|
||||
void this.spawn("radicle-httpd", ["--listen", `0.0.0.0:${port}`]);
|
||||
|
||||
await waitOn({
|
||||
resources: [`tcp:127.0.0.1:${port}`],
|
||||
@@ -215,7 +213,6 @@ export class RadiclePeer {
|
||||
args.push("--tracking-policy", params.trackingPolicy);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
void this.spawn("radicle-node", args);
|
||||
|
||||
await waitOn({
|
||||
@@ -242,43 +239,6 @@ export class RadiclePeer {
|
||||
);
|
||||
}
|
||||
|
||||
// Create a project using the rad CLI.
|
||||
public async createProject(
|
||||
name: string,
|
||||
description = "",
|
||||
defaultBranch = "main",
|
||||
): Promise<{ rid: string; projectFolder: string }> {
|
||||
const projectFolder = Path.join(this.checkoutPath, name);
|
||||
|
||||
await this.git(["init", name, "--initial-branch", defaultBranch], {
|
||||
cwd: this.checkoutPath,
|
||||
});
|
||||
await this.git(["commit", "--allow-empty", "--message", "initial commit"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await this.rad(
|
||||
[
|
||||
"init",
|
||||
"--name",
|
||||
name,
|
||||
"--default-branch",
|
||||
defaultBranch,
|
||||
"--description",
|
||||
description,
|
||||
"--announce",
|
||||
],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
|
||||
const { stdout: rid } = await this.rad(["inspect"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
|
||||
return { rid, projectFolder };
|
||||
}
|
||||
|
||||
public async waitForRoutes(rid: string, ...nodes: string[]) {
|
||||
let remaining = nodes;
|
||||
|
||||
@@ -364,8 +324,7 @@ export class RadiclePeer {
|
||||
};
|
||||
const childProcess = Process.spawn(cmd, args, opts);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
Process.prefixOutput(childProcess, this.nodeId, this.#outputLog);
|
||||
void Process.prefixOutput(childProcess, this.nodeId, this.#outputLog);
|
||||
|
||||
return childProcess;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import type { RadiclePeer } from "@tests/support/peerManager";
|
||||
|
||||
import * as Path from "node:path";
|
||||
|
||||
// Create a project using the rad CLI.
|
||||
export async function createProject(
|
||||
peer: RadiclePeer,
|
||||
name: string,
|
||||
description = "",
|
||||
defaultBranch = "main",
|
||||
): Promise<{ rid: string; projectFolder: string }> {
|
||||
const projectFolder = Path.join(peer.checkoutPath, name);
|
||||
|
||||
await peer.git(["init", name, "--initial-branch", defaultBranch], {
|
||||
cwd: peer.checkoutPath,
|
||||
});
|
||||
await peer.git(["commit", "--allow-empty", "--message", "initial commit"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await peer.rad(
|
||||
[
|
||||
"init",
|
||||
"--name",
|
||||
name,
|
||||
"--default-branch",
|
||||
defaultBranch,
|
||||
"--description",
|
||||
description,
|
||||
"--announce",
|
||||
],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
|
||||
const { stdout: rid } = await peer.rad(["inspect"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
|
||||
return { rid, projectFolder };
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
import * as sinon from "sinon";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
@@ -61,14 +60,14 @@ describe("executor", () => {
|
||||
const e = mutexExecutor.create();
|
||||
const abortListener = sinon.spy();
|
||||
|
||||
e.run(async abort => {
|
||||
void e.run(async abort => {
|
||||
abort.addEventListener("abort", abortListener);
|
||||
await sleep(10);
|
||||
return "first";
|
||||
});
|
||||
expect(abortListener.called).toBe(false);
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
e.run(async () => {});
|
||||
void e.run(async () => {});
|
||||
expect(abortListener.called).toBe(true);
|
||||
});
|
||||
|
||||
@@ -113,9 +112,9 @@ describe("worker", () => {
|
||||
|
||||
const nextOutput = w.output.firstToPromise();
|
||||
|
||||
w.submit(1);
|
||||
w.submit(2);
|
||||
w.submit(3);
|
||||
void w.submit(1);
|
||||
void w.submit(2);
|
||||
void w.submit(3);
|
||||
|
||||
expect(await nextOutput).toEqual(3);
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { test, expect, projectFixtureUrl } from "@tests/support/fixtures.js";
|
||||
import { test, expect, markdownUrl } from "@tests/support/fixtures.js";
|
||||
|
||||
async function goToSection(section: string, page: Page) {
|
||||
await page.goto(`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md`, {
|
||||
await page.goto(`${markdownUrl}/tree/main/cheatsheet.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await page.locator(`[href="${section}"]`).click();
|
||||
@@ -13,7 +13,7 @@ test.describe("markdown rendering", async () => {
|
||||
test.use({ viewport: { width: 1280, height: 450 } });
|
||||
test("table of contents", async ({ page }) => {
|
||||
await page.goto(
|
||||
`${projectFixtureUrl}/tree/main/markdown/cheatsheet.md#table-of-contents`,
|
||||
`${markdownUrl}/tree/main/cheatsheet.md#table-of-contents`,
|
||||
{
|
||||
waitUntil: "networkidle",
|
||||
},
|
||||
@@ -80,11 +80,31 @@ test.describe("markdown rendering", async () => {
|
||||
});
|
||||
|
||||
test.describe(async () => {
|
||||
test.use({ viewport: { width: 1280, height: 590 } });
|
||||
test("footnotes", async ({ page }) => {
|
||||
await goToSection("#footnotes", page);
|
||||
await expect(page.locator("text=Footnotes aren't part")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot();
|
||||
await page.goto(`${markdownUrl}/tree/main/footnotes.md#footnotes`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=This is an example footnote[0]. And some radicle[1] examples.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(page.locator("text=0. https://example.com ↩")).toBeVisible();
|
||||
await expect(page.locator("text=1. https://radicle.xyz ↩")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
|
||||
await page.locator("text=Plain").click();
|
||||
await expect(
|
||||
page.locator(
|
||||
"text=This is an example footnote[^0]. And some radicle[^1] examples.",
|
||||
),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=[^0]: https://example.com"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.locator("text=[^1]: https://radicle.xyz"),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -146,3 +166,10 @@ test.describe("markdown rendering", async () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test("relative image not able to being loaded", async ({ page }) => {
|
||||
await page.goto(`${markdownUrl}/tree/main/loading-image.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
test,
|
||||
expect,
|
||||
projectFixtureUrl,
|
||||
sourceBrowsingUrl,
|
||||
aliceRemote,
|
||||
} from "@tests/support/fixtures.js";
|
||||
|
||||
test("source tree page", async ({ page }) => {
|
||||
await page.goto(projectFixtureUrl, { waitUntil: "networkidle" });
|
||||
await page.goto(sourceBrowsingUrl, { waitUntil: "networkidle" });
|
||||
await expect(page).toHaveScreenshot();
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ test("commits page", async ({ page }) => {
|
||||
});
|
||||
|
||||
await page.goto(
|
||||
`${projectFixtureUrl}/remotes/${aliceRemote.substring(8)}/history`,
|
||||
`${sourceBrowsingUrl}/remotes/${aliceRemote.substring(8)}/history`,
|
||||
{
|
||||
waitUntil: "networkidle",
|
||||
},
|
||||
@@ -43,17 +43,10 @@ test("commit page", async ({ page }) => {
|
||||
});
|
||||
|
||||
await page.goto(
|
||||
`${projectFixtureUrl}/remotes/${aliceRemote.substring(
|
||||
`${sourceBrowsingUrl}/remotes/${aliceRemote.substring(
|
||||
8,
|
||||
)}/commits/d6318f7f3d9c15b8ac6dd52267c53220d00f0982`,
|
||||
);
|
||||
await expect(page.locator("text=subconscious.txt added")).toBeVisible();
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
test("relative image not able to being loaded", async ({ page }) => {
|
||||
await page.goto(`${projectFixtureUrl}/tree/main/markdown/loading-image.md`, {
|
||||
waitUntil: "networkidle",
|
||||
});
|
||||
await expect(page).toHaveScreenshot({ fullPage: true });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user