From 91f5abafd3cba78689158d348c13da36ce45ca4b Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Mon, 12 Jun 2023 12:35:03 +0200 Subject: [PATCH] Add a UI test flow for issues Tests: - Authentication - Issue creation - Title editing - Commenting - Reply to comment - Issue state change Signed-off-by: Sebastian Martinez --- src/views/projects/Cob/AssigneeInput.svelte | 2 +- src/views/projects/Cob/CobStateButton.svelte | 2 +- src/views/projects/Cob/TagInput.svelte | 2 +- tests/e2e/httpd.spec.ts | 29 --------- tests/e2e/project/issues.spec.ts | 67 ++++++++++++++++++++ tests/support/fixtures.ts | 32 ++++++++-- 6 files changed, 97 insertions(+), 37 deletions(-) delete mode 100644 tests/e2e/httpd.spec.ts diff --git a/src/views/projects/Cob/AssigneeInput.svelte b/src/views/projects/Cob/AssigneeInput.svelte index 961b63594..50dd64750 100644 --- a/src/views/projects/Cob/AssigneeInput.svelte +++ b/src/views/projects/Cob/AssigneeInput.svelte @@ -101,7 +101,7 @@ on:remove={removeAssignee} removeable={editInProgress || action === "create"} {key}> -
+
{formatNodeId(assignee)}
diff --git a/src/views/projects/Cob/CobStateButton.svelte b/src/views/projects/Cob/CobStateButton.svelte index fdf6fb4ed..7a057cf33 100644 --- a/src/views/projects/Cob/CobStateButton.svelte +++ b/src/views/projects/Cob/CobStateButton.svelte @@ -64,7 +64,7 @@ - diff --git a/src/views/projects/Cob/TagInput.svelte b/src/views/projects/Cob/TagInput.svelte index f2f1d0005..8e018bbcd 100644 --- a/src/views/projects/Cob/TagInput.svelte +++ b/src/views/projects/Cob/TagInput.svelte @@ -96,7 +96,7 @@ on:remove={removeTag} removeable={editInProgress || action === "create"} {key}> -
{tag}
+
{tag}
{:else}
No tags
diff --git a/tests/e2e/httpd.spec.ts b/tests/e2e/httpd.spec.ts deleted file mode 100644 index ae3c066cb..000000000 --- a/tests/e2e/httpd.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { test, expect } from "@tests/support/fixtures.js"; - -test("change httpd port", async ({ page, peerManager }) => { - const peer = await peerManager.startPeer({ name: "httpd" }); - - await peer.startHttpd(8070); - 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"]').press("Enter"); - - const { stdout } = await peer.rad([ - "web", - "--frontend", - "http://localhost:3000", - "--backend", - "http://127.0.0.1:8070", - ]); - const match = stdout.trim().match(/(http:\/\/localhost:3000\/.*)$/); - if (!match) { - throw Error("Not able to parse auth url"); - } - await page.goto(match[0]); - await expect(page.getByText("Authenticated")).toBeVisible(); - await expect(page).toHaveURL("/seeds/127.0.0.1:8070"); -}); diff --git a/tests/e2e/project/issues.spec.ts b/tests/e2e/project/issues.spec.ts index e19e2b0ce..3956b0b87 100644 --- a/tests/e2e/project/issues.spec.ts +++ b/tests/e2e/project/issues.spec.ts @@ -55,3 +55,70 @@ test("test issue editing failing", async ({ page, authenticatedPeer }) => { await page.getByRole("button", { name: "Comment" }).click(); await expect(page.getByText("Issue editing failed")).toBeVisible(); }); + +test("go through the entire ui issue flow", async ({ + page, + authenticatedPeer, +}) => { + const { rid } = await createProject(authenticatedPeer, "commenting"); + + await page.goto(`/seeds/127.0.0.1:8070/${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"); + await page + .getByPlaceholder("Write a description") + .fill("This is a description"); + + await page.getByPlaceholder("Add assignee").fill(authenticatedPeer.nodeId); + await page.getByPlaceholder("Add assignee").press("Enter"); + + await page.getByPlaceholder("Add tag").fill("bug"); + await page.getByPlaceholder("Add tag").press("Enter"); + await page.getByPlaceholder("Add tag").fill("documentation"); + await page.getByPlaceholder("Add tag").press("Enter"); + + await page.getByRole("button", { name: "Submit" }).click(); + + await expect(page.getByText("This is a title")).toBeVisible(); + await expect(page.getByText("This is a description")).toBeVisible(); + await expect( + page.getByLabel("chip").filter({ + hasText: `did:key:${authenticatedPeer.nodeId.substring( + 0, + 6, + )}…${authenticatedPeer.nodeId.slice(-6)}`, + }), + ).toBeVisible(); + await expect( + page.getByLabel("chip").filter({ hasText: "documentation" }), + ).toBeVisible(); + await expect( + page.getByLabel("chip").filter({ hasText: "bug" }), + ).toBeVisible(); + + await page.getByRole("button", { name: "edit" }).first().click(); + await page.getByPlaceholder("Title").fill("This is a new title"); + await page.getByRole("button", { name: "save" }).click(); + await expect(page.getByText("This is a new title")).toBeVisible(); + + await page.getByPlaceholder("Leave your comment").fill("This is a comment"); + await page.getByRole("button", { name: "Comment" }).click(); + await expect(page.getByText("This is a comment")).toBeVisible(); + + await page.getByRole("button", { name: "reply" }).click(); + await page.getByPlaceholder("Leave your reply").fill("This is a reply"); + await page.getByRole("button", { name: "Reply", exact: true }).click(); + await expect(page.getByText("This is a reply")).toBeVisible(); + + await page.getByRole("button", { name: "Close issue as solved" }).click(); + await expect(page.getByText("closed as solved")).toBeVisible(); + + await page.getByRole("button", { name: "Reopen issue" }).click(); + await expect(page.getByText("open", { exact: true })).toBeVisible(); + + await page.getByRole("button", { name: "stateToggle" }).click(); + await page.getByText("Close issue as other").click(); + await page.getByRole("button", { name: "Close issue as other" }).click(); + await expect(page.getByText("closed as other")).toBeVisible(); +}); diff --git a/tests/support/fixtures.ts b/tests/support/fixtures.ts index ad4490d53..357500769 100644 --- a/tests/support/fixtures.ts +++ b/tests/support/fixtures.ts @@ -14,6 +14,7 @@ import * as patch from "@tests/support/cobs/patch.js"; import { createOptions, supportDir, tmpDir } from "@tests/support/support.js"; import { createPeerManager } from "@tests/support/peerManager.js"; import { createProject } from "@tests/support/project.js"; +import { object, string, ZodSchema } from "zod"; export { expect }; @@ -21,6 +22,18 @@ const fixturesDir = Path.resolve(supportDir, "..", "./fixtures"); type ViewportTypes = "iPhoneXR" | "Desktop"; +interface Auth { + sessionId: string; + publicKey: string; + signature: string; +} + +const authSchema = object({ + sessionId: string(), + publicKey: string(), + signature: string(), +}) satisfies ZodSchema; + export const viewportSizes: Record = { iPhoneXR: { width: 414, height: 896 }, Desktop: { width: 1280, height: 720 }, @@ -164,15 +177,24 @@ export const test = base.extend<{ "http://localhost:3000", "--backend", "http://127.0.0.1:8070", + "--json", ]); - const match = stdout.trim().match(/(http:\/\/localhost:3000\/.*)$/); - if (!match) { - throw Error("Not able to parse auth url"); + const result = authSchema.safeParse(JSON.parse(stdout)); + if (result.success) { + const { sessionId, publicKey, signature } = result.data; + await page.goto( + `http://localhost:3000/session/${sessionId}?pk=${publicKey}&sig=${signature}`, + ); + await expect(page.getByText("Authenticated")).toBeVisible(); + await page.getByRole("button", { name: "Close" }).click(); + } else { + throw new Error("Not able to parse rad web output"); } - await page.goto(match[0]); - await page.getByRole("button", { name: "Close" }).click(); await use(peer); + + await peer.stopHttpd(8070); + await peer.stopNode(); }, // eslint-disable-next-line no-empty-pattern