mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-08 13:10:44 +08:00
Add e2e tests for editing patches, issues, comments, labels and assignees
This commit is contained in:
@@ -98,6 +98,7 @@
|
||||
<div class="actions">
|
||||
{#if mode === "readEdit"}
|
||||
<IconButton
|
||||
title="save assignees"
|
||||
loading={submitInProgress}
|
||||
on:click={() => {
|
||||
dispatch("save", updatedAssignees);
|
||||
@@ -106,6 +107,7 @@
|
||||
<IconSmall name="checkmark" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
title="dismiss changes"
|
||||
loading={submitInProgress}
|
||||
on:click={() => {
|
||||
updatedAssignees = assignees;
|
||||
@@ -116,6 +118,7 @@
|
||||
</IconButton>
|
||||
{:else if mode !== "readCreate"}
|
||||
<IconButton
|
||||
title="edit assignees"
|
||||
loading={submitInProgress}
|
||||
on:click={() => (mode = "readEdit")}>
|
||||
<IconSmall name="edit" />
|
||||
@@ -131,11 +134,11 @@
|
||||
<div class="assignee">
|
||||
<Avatar inline nodeId={assignee} />
|
||||
<span>{formatNodeId(assignee)}</span>
|
||||
<span style:cursor="pointer">
|
||||
<IconButton title="remove assignee">
|
||||
<IconSmall
|
||||
name="cross"
|
||||
on:click={() => removeAssignee(assignee)} />
|
||||
</span>
|
||||
</IconButton>
|
||||
</div>
|
||||
</Badge>
|
||||
{:else}
|
||||
|
||||
@@ -120,9 +120,9 @@
|
||||
{#each updatedLabels as label}
|
||||
<Badge variant="neutral">
|
||||
<div aria-label="chip" class="label">{label}</div>
|
||||
<span style:cursor="pointer">
|
||||
<IconButton title="remove label">
|
||||
<IconSmall name="cross" on:click={() => removeLabel(label)} />
|
||||
</span>
|
||||
</IconButton>
|
||||
</Badge>
|
||||
{:else}
|
||||
<div class="txt-missing">No labels</div>
|
||||
|
||||
@@ -675,7 +675,7 @@
|
||||
body={newDescription}
|
||||
submitCaption="Save"
|
||||
submitInProgress={descriptionState === "submit"}
|
||||
placeholder="Leave your description"
|
||||
placeholder="Leave a description"
|
||||
on:close={() => (descriptionState = "read")}
|
||||
on:submit={async ({ detail: { comment } }) => {
|
||||
descriptionState = "submit";
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import { test, expect } from "@tests/support/fixtures.js";
|
||||
import { createProject } from "@tests/support/project";
|
||||
|
||||
test("add and remove assignees", async ({ page, authenticatedPeer }) => {
|
||||
await page.goto(authenticatedPeer.uiUrl());
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"handle-assignees",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to test assignee handling",
|
||||
"--description",
|
||||
"We'll add and remove assignees to them",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/4fe061828a067ae52bda43537ca61b7aeeb44563`,
|
||||
);
|
||||
|
||||
await expect(page.getByText("No assignees")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit assignees" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Add assignee")
|
||||
.fill("z6MktULudTtAsAhRegYPiZ6631RV3viv12qd4GQF8z1xB22S");
|
||||
await page.getByRole("button", { name: "dismiss changes" }).click();
|
||||
await expect(page.getByText("No assignees")).toBeVisible();
|
||||
await page.getByRole("button", { name: "edit assignees" }).click();
|
||||
await expect(page.getByPlaceholder("Add assignee")).toHaveValue("");
|
||||
|
||||
await page
|
||||
.getByPlaceholder("Add assignee")
|
||||
.fill("z6MktULudTtAsAhRegYPiZ6631RV3viv12qd4GQF8z1xB22S");
|
||||
await page.keyboard.press("Enter");
|
||||
await page
|
||||
.getByPlaceholder("Add assignee")
|
||||
.fill("z6MktULudTtAsAhRegYPiZ6631RV3viv12qd4GQF8z1xB22S");
|
||||
await expect(page.getByText("This assignee is already added")).toBeVisible();
|
||||
await page.getByPlaceholder("Add assignee").clear();
|
||||
await expect(page.getByText("This assignee is already added")).toBeHidden();
|
||||
|
||||
await page
|
||||
.getByPlaceholder("Add assignee")
|
||||
.fill("z6MkkfM3tPXNPrPevKr3uSiQtHPuwnNhu2yUVjgd2jXVsVz5");
|
||||
await page.keyboard.press("Enter");
|
||||
await page.getByRole("button", { name: "save assignees" }).click();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "save assignees" }),
|
||||
).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "avatar did:key:z6MktU…1xB22S" }),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "avatar did:key:z6Mkkf…XVsVz5" }),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit assignees" }).click();
|
||||
await page
|
||||
.getByRole("button", {
|
||||
name: "avatar did:key:z6MktU…1xB22S remove assignee",
|
||||
})
|
||||
.getByTitle("remove assignee")
|
||||
.click();
|
||||
await page.getByRole("button", { name: "save assignees" }).click();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "save assignees" }),
|
||||
).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "avatar did:key:z6Mkkf…XVsVz5" }),
|
||||
).toBeVisible();
|
||||
});
|
||||
@@ -0,0 +1,161 @@
|
||||
import { test, cobUrl, expect } from "@tests/support/fixtures.js";
|
||||
import { createProject, expectReactionsToWork } from "@tests/support/project";
|
||||
|
||||
test("navigate single issue", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/issues`);
|
||||
await page.getByText("This title has markdown").click();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/issues/d72196335761c1d5fa7883f6620e7334b34e38f9`,
|
||||
);
|
||||
});
|
||||
|
||||
test("test issue editing failing", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"issue-editing",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This issue is going to fail",
|
||||
"--description",
|
||||
"Let's see",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
|
||||
await page.route(
|
||||
`**/v1/projects/${rid}/issues/ecd5f103110b08b93bede17163d35de1e1068148`,
|
||||
route => {
|
||||
if (route.request().method() !== "PATCH") {
|
||||
void route.fallback();
|
||||
return;
|
||||
}
|
||||
void route.fulfill({ status: 500 });
|
||||
},
|
||||
);
|
||||
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/ecd5f103110b08b93bede17163d35de1e1068148`,
|
||||
);
|
||||
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).first().click();
|
||||
await expect(page.getByText("Comment creation failed")).toBeVisible();
|
||||
});
|
||||
|
||||
test("edit title", async ({ page, authenticatedPeer }) => {
|
||||
await page.goto(authenticatedPeer.uiUrl());
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"edit-title",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to edit its title",
|
||||
"--description",
|
||||
"We'll give it a title and edit it.",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/616e240787b6527780636caae581ca9975060733`,
|
||||
);
|
||||
|
||||
await expect(
|
||||
page.getByText("This is an issue to edit its title"),
|
||||
).toBeVisible();
|
||||
await expect(page.getByPlaceholder("Title")).toBeHidden();
|
||||
|
||||
await page.getByRole("button", { name: "edit title" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Title")
|
||||
.fill("This is a modified issue title to be dismissed");
|
||||
await page.getByRole("button", { name: "dismiss changes" }).click();
|
||||
await expect(
|
||||
page.getByText("This is an issue to edit its title"),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit title" }).click();
|
||||
await page.getByPlaceholder("Title").fill("This is a modified issue title");
|
||||
await page.getByRole("button", { name: "save title" }).click();
|
||||
await expect(page.getByRole("button", { name: "save title" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByText("This is a modified issue title")).toBeVisible();
|
||||
});
|
||||
|
||||
test("edit description", async ({ page, authenticatedPeer }) => {
|
||||
await page.goto(authenticatedPeer.uiUrl());
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"edit-description",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to edit its description",
|
||||
"--description",
|
||||
"We'll give it a description and edit it.",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/335e2823a71ac91203913a484dd771fd79f75139`,
|
||||
);
|
||||
|
||||
await expect(
|
||||
page.getByText("We'll give it a description and edit it."),
|
||||
).toBeVisible();
|
||||
await expect(page.getByPlaceholder("Leave a description")).toBeHidden();
|
||||
|
||||
await page.getByRole("button", { name: "edit description" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Leave a description")
|
||||
.fill("This is a modified issue description to be dismissed");
|
||||
await page.getByRole("button", { name: "Cancel" }).click();
|
||||
await expect(
|
||||
page.getByText("We'll give it a description and edit it."),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit description" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Leave a description")
|
||||
.fill("This is a modified issue description");
|
||||
await page.getByRole("button", { name: "Save" }).click();
|
||||
await expect(page.getByRole("button", { name: "Save" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByText("This is a modified issue description"),
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("add and remove reactions", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"handle-reactions",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to test reactions",
|
||||
"--description",
|
||||
"We'll add and remove reactions to them",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/cb5f9b2de24ecfdd293a607c96d78aacc911b589`,
|
||||
);
|
||||
await expectReactionsToWork(page);
|
||||
});
|
||||
@@ -1,6 +1,5 @@
|
||||
import { test, cobUrl, expect } from "@tests/support/fixtures.js";
|
||||
import { createProject } from "@tests/support/project";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { addEmbed, createProject } from "@tests/support/project";
|
||||
|
||||
test("navigate issue listing", async ({ page }) => {
|
||||
await page.goto(cobUrl);
|
||||
@@ -12,60 +11,7 @@ test("navigate issue listing", async ({ page }) => {
|
||||
await expect(page).toHaveURL(`${cobUrl}/issues?state=closed`);
|
||||
});
|
||||
|
||||
test("navigate single issue", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/issues`);
|
||||
await page.getByText("This title has markdown").click();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/issues/d72196335761c1d5fa7883f6620e7334b34e38f9`,
|
||||
);
|
||||
});
|
||||
|
||||
test("adding and removing reactions", async ({ page, authenticatedPeer }) => {
|
||||
await page.goto(authenticatedPeer.uiUrl());
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"handle-reactions",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to test reactions",
|
||||
"--description",
|
||||
"We'll write some comments and add and remove reactions to them",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/a9d83773ac2fb8f5f654640477b9225a684cb53f`,
|
||||
);
|
||||
const commentReactionToggle = page
|
||||
.getByTitle("toggle-reaction-popover")
|
||||
.last();
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).first().click();
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "👍" }).click();
|
||||
await expect(page.getByRole("button", { name: "👍 1" })).toBeVisible();
|
||||
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "🎉" }).click();
|
||||
await expect(page.getByRole("button", { name: "🎉 1" })).toBeVisible();
|
||||
await expect(page.locator(".reaction")).toHaveCount(2);
|
||||
|
||||
await page.getByRole("button", { name: "👍" }).click();
|
||||
await expect(page.locator("span").filter({ hasText: "👍 1" })).toBeHidden();
|
||||
await expect(page.locator(".reaction")).toHaveCount(1);
|
||||
|
||||
await page.getByRole("button", { name: "🎉" }).click();
|
||||
await expect(page.locator("span").filter({ hasText: "🎉 1" })).toBeHidden();
|
||||
await expect(page.locator(".reaction")).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("test issue counters", async ({ page, authenticatedPeer }) => {
|
||||
test("issue counters", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"issue-counters",
|
||||
@@ -108,48 +54,7 @@ test("test issue counters", async ({ page, authenticatedPeer }) => {
|
||||
await expect(page.getByRole("button", { name: "1 issue" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("test issue editing failing", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"issue-editing",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This issue is going to fail",
|
||||
"--description",
|
||||
"Let's see",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
|
||||
await page.route(
|
||||
`**/v1/projects/${rid}/issues/ecd5f103110b08b93bede17163d35de1e1068148`,
|
||||
route => {
|
||||
if (route.request().method() !== "PATCH") {
|
||||
void route.fallback();
|
||||
return;
|
||||
}
|
||||
void route.fulfill({ status: 500 });
|
||||
},
|
||||
);
|
||||
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/ecd5f103110b08b93bede17163d35de1e1068148`,
|
||||
);
|
||||
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).first().click();
|
||||
await expect(page.getByText("Comment creation failed")).toBeVisible();
|
||||
});
|
||||
|
||||
test("go through the entire ui issue flow", async ({
|
||||
page,
|
||||
authenticatedPeer,
|
||||
}) => {
|
||||
test("create a new issue", async ({ page, authenticatedPeer }) => {
|
||||
const { rid } = await createProject(authenticatedPeer, "commenting");
|
||||
|
||||
await page.goto(
|
||||
@@ -185,60 +90,23 @@ test("go through the entire ui issue flow", async ({
|
||||
page.locator(".badge").filter({ hasText: "documentation" }),
|
||||
).toBeVisible();
|
||||
await expect(page.locator(".badge").filter({ hasText: "bug" })).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit title" }).click();
|
||||
await page.getByPlaceholder("Title").fill("This is a new title");
|
||||
await page.getByRole("button", { name: "save title" }).click();
|
||||
await expect(page.getByText("This is a new title")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).first().click();
|
||||
await expect(page.getByText("This is a comment")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Reply to comment" }).click();
|
||||
await page.getByPlaceholder("Reply to comment").fill("This is a reply");
|
||||
await page.getByRole("button", { name: "Comment", 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" }).first().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();
|
||||
});
|
||||
|
||||
test("handling embeds", async ({ page, authenticatedPeer }) => {
|
||||
const buffer = await readFile("./public/images/radicle-228x228.png");
|
||||
const base64Data = buffer.toString("base64");
|
||||
const { rid } = await createProject(authenticatedPeer, "embeds");
|
||||
|
||||
await page.goto(
|
||||
`/nodes/${authenticatedPeer.httpdBaseUrl.hostname}:${authenticatedPeer.httpdBaseUrl.port}/${rid}/issues/new`,
|
||||
);
|
||||
|
||||
const dataTransfer = await page.evaluateHandle(data => {
|
||||
const arrayBuffer = Uint8Array.from(atob(data), c => c.charCodeAt(0));
|
||||
const dt = new DataTransfer();
|
||||
const file = new File([arrayBuffer.buffer], "radicle-228x228.png", {
|
||||
type: "image/png",
|
||||
});
|
||||
dt.items.add(file);
|
||||
return dt;
|
||||
}, base64Data);
|
||||
|
||||
await page.getByPlaceholder("Title").fill("This is a title");
|
||||
await page
|
||||
.getByPlaceholder("Write a description")
|
||||
.fill("Here is some text\n\n");
|
||||
await page.dispatchEvent("textarea[aria-label=textarea-comment]", "drop", {
|
||||
dataTransfer,
|
||||
});
|
||||
await addEmbed(
|
||||
page,
|
||||
"./public/images/radicle-228x228.png",
|
||||
"radicle-228x228.png",
|
||||
"image/png",
|
||||
);
|
||||
await expect(page.getByPlaceholder("Write a description")).toHaveValue(
|
||||
"Here is some text\n\n\n",
|
||||
);
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { test } from "@tests/support/fixtures.js";
|
||||
import {
|
||||
createProject,
|
||||
expectLabelEditingToWork,
|
||||
extractPatchId,
|
||||
} from "@tests/support/project";
|
||||
|
||||
test("add and remove labels", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"handle-labels",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to test label handling",
|
||||
"--description",
|
||||
"We'll add and remove labels to them",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/5129d02476bc8c85f35e06a7d19dde487b0a8b13`,
|
||||
);
|
||||
await expectLabelEditingToWork(page);
|
||||
|
||||
await authenticatedPeer.git(["switch", "-c", "handle-labels"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await expectLabelEditingToWork(page);
|
||||
});
|
||||
@@ -0,0 +1,246 @@
|
||||
import { test, cobUrl, expect } from "@tests/support/fixtures.js";
|
||||
import { createProject, extractPatchId } from "@tests/support/project";
|
||||
|
||||
test("navigate patch details", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches`);
|
||||
await page.getByText("Add subtitle to README").click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/1cd7fe9598c0a877c32c516bddb3de70dfb53366`,
|
||||
);
|
||||
await page.getByRole("link", { name: "Add subtitle to README" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/commits/8c900d6cb38811e099efb3cbbdbfaba817bcf970`,
|
||||
);
|
||||
await page.goBack();
|
||||
{
|
||||
await page.getByRole("link", { name: "Changes" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/1cd7fe9598c0a877c32c516bddb3de70dfb53366?tab=changes`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("use revision selector", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a`);
|
||||
await page.getByRole("link", { name: "Changes" }).click();
|
||||
|
||||
// Validating the latest revision state
|
||||
await expect(
|
||||
page.getByRole("cell", { name: "Had to push a new revision" }),
|
||||
).toBeVisible();
|
||||
await page.getByRole("link", { name: "Activity" }).click();
|
||||
await expect(page.locator(".commits .teaser")).toHaveCount(2);
|
||||
await expect(page.getByRole("link", { name: "Add more text" })).toBeVisible();
|
||||
|
||||
// Open the first revision and close the latest one
|
||||
await page.getByLabel("expand").first().click();
|
||||
await page.getByLabel("expand").last().click();
|
||||
|
||||
// Validating the initial revision
|
||||
await expect(page.locator(".commits .teaser")).toHaveCount(1);
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Rewrite subtitle to README" }),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("link", { name: "Changes" }).click();
|
||||
// Switching to the initial revision
|
||||
await page.getByText("Revision 2c2f036").click();
|
||||
await expect(page.locator(".dropdown")).toBeVisible();
|
||||
await page.getByRole("link", { name: "Revision 679b2c8" }).click();
|
||||
await expect(page.locator(".dropdown")).toBeHidden();
|
||||
|
||||
await expect(
|
||||
page.getByRole("cell", { name: "Had to push a new revision" }),
|
||||
).toBeHidden();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a/679b2c84a8e15ce1f73c4c231b55431b89b2559a?tab=changes`,
|
||||
);
|
||||
});
|
||||
|
||||
test("navigate through revision diffs", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a`);
|
||||
|
||||
const firstRevision = page.locator(".revision").first();
|
||||
const secondRevision = page.locator(".revision").nth(1);
|
||||
|
||||
// Second revision
|
||||
{
|
||||
await secondRevision
|
||||
.getByRole("button", { name: "toggle-context-menu" })
|
||||
.first()
|
||||
.click();
|
||||
await secondRevision
|
||||
.getByRole("link", { name: "Compare to main: 38c225e" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 38c225..9898da" }),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a?diff=38c225e2a0b47ba59def211f4e4825c31d9463ec..9898da6155467adad511f63bf0fb5aa4156b92ef`,
|
||||
);
|
||||
await page.goBack();
|
||||
await secondRevision
|
||||
.getByRole("button", { name: "toggle-context-menu" })
|
||||
.first()
|
||||
.click();
|
||||
await secondRevision
|
||||
.getByRole("link", { name: "Compare to previous revision: 679b2c8" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 0dc373..9898da" }),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a?diff=0dc373db601ccbcffa80dec932e4006516709ca6..9898da6155467adad511f63bf0fb5aa4156b92ef`,
|
||||
);
|
||||
await page.goBack();
|
||||
|
||||
await secondRevision
|
||||
.getByRole("link", { name: "Compare 0dc373d..9898da6" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 0dc373..9898da" }),
|
||||
).toBeVisible();
|
||||
await page.goBack();
|
||||
}
|
||||
// First revision
|
||||
{
|
||||
await firstRevision
|
||||
.getByRole("button", { name: "toggle-context-menu" })
|
||||
.first()
|
||||
.click();
|
||||
await firstRevision
|
||||
.getByRole("link", { name: "Compare to main: 38c225e" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 38c225..0dc373" }),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a?diff=38c225e2a0b47ba59def211f4e4825c31d9463ec..0dc373db601ccbcffa80dec932e4006516709ca6`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("view file navigation from changes tab", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a`);
|
||||
await page.getByRole("button", { name: "Changes" }).click();
|
||||
await page.getByRole("button", { name: "View file" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/tree/9898da6155467adad511f63bf0fb5aa4156b92ef/README.md`,
|
||||
);
|
||||
});
|
||||
|
||||
test("change patch state", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"lifecycle",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await page.getByRole("button", { name: "Archive patch" }).first().click();
|
||||
await expect(page.getByText("archived", { exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "0 patches" })).toBeVisible();
|
||||
|
||||
await page.getByLabel("stateToggle").first().click();
|
||||
await page.getByText("Convert to draft").click();
|
||||
await page.getByText("Convert to draft").click();
|
||||
await expect(page.getByText("draft", { exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "0 patches" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("edit title", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"edit-title",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "edit-title"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
|
||||
const titleLocator = page.getByText("Some patch title").first();
|
||||
await expect(titleLocator).toBeVisible();
|
||||
await expect(page.getByPlaceholder("Title")).toBeHidden();
|
||||
|
||||
await page.getByRole("button", { name: "edit title" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Title")
|
||||
.fill("This is a modified patch title to be dismissed");
|
||||
await page.getByRole("button", { name: "dismiss changes" }).click();
|
||||
await expect(titleLocator).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit title" }).click();
|
||||
await page.getByPlaceholder("Title").fill("This is a modified patch title");
|
||||
await page.getByRole("button", { name: "save title" }).click();
|
||||
await expect(page.getByRole("button", { name: "save title" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByText("This is a modified patch title")).toBeVisible();
|
||||
});
|
||||
|
||||
test("edit description", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"edit-description",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "edit-description"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
|
||||
await expect(page.getByText("No description available")).toBeVisible();
|
||||
await expect(page.getByPlaceholder("Leave a description")).toBeHidden();
|
||||
|
||||
await page.getByRole("button", { name: "edit description" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Leave a description")
|
||||
.fill("This is a modified patch description to be dismissed");
|
||||
await page.getByRole("button", { name: "Cancel" }).click();
|
||||
await expect(page.getByText("No description available")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit description" }).click();
|
||||
await page
|
||||
.getByPlaceholder("Leave a description")
|
||||
.fill("This is a modified patch description");
|
||||
await page.getByRole("button", { name: "Save" }).click();
|
||||
await expect(page.getByRole("button", { name: "Save" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(
|
||||
page.getByText("This is a modified patch description"),
|
||||
).toBeVisible();
|
||||
});
|
||||
@@ -1,16 +1,6 @@
|
||||
import type { ExecaReturnValue } from "execa";
|
||||
import { test, cobUrl, expect } from "@tests/support/fixtures.js";
|
||||
import { createProject } from "@tests/support/project";
|
||||
|
||||
function extractPatchId(cmdOutput: ExecaReturnValue<string>) {
|
||||
const match = cmdOutput.stderr.match(/[0-9a-f]{40}/);
|
||||
if (match) {
|
||||
return match[0];
|
||||
} else {
|
||||
throw new Error("Could not get patch id");
|
||||
}
|
||||
}
|
||||
|
||||
test("navigate patch listing", async ({ page }) => {
|
||||
await page.goto(cobUrl);
|
||||
await page.getByRole("link", { name: "2 patches" }).click();
|
||||
@@ -24,165 +14,6 @@ test("navigate patch listing", async ({ page }) => {
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("navigate patch details", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches`);
|
||||
await page.getByText("Add subtitle to README").click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/1cd7fe9598c0a877c32c516bddb3de70dfb53366`,
|
||||
);
|
||||
await page.getByRole("link", { name: "Add subtitle to README" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/commits/8c900d6cb38811e099efb3cbbdbfaba817bcf970`,
|
||||
);
|
||||
await page.goBack();
|
||||
{
|
||||
await page.getByRole("link", { name: "Changes" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/1cd7fe9598c0a877c32c516bddb3de70dfb53366?tab=changes`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("edit a patch", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"commenting",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await expect(page.getByRole("button", { name: "1 patch" })).toBeVisible();
|
||||
await expect(page.getByText("open", { exact: true })).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit labels" }).click();
|
||||
await page.getByPlaceholder("Add label").fill("bug");
|
||||
await page.getByPlaceholder("Add label").press("Enter");
|
||||
await page.getByPlaceholder("Add label").fill("documentation");
|
||||
await page.getByPlaceholder("Add label").press("Enter");
|
||||
await page.getByRole("button", { name: "save labels" }).click();
|
||||
|
||||
await expect(
|
||||
page.locator(".badge").filter({ hasText: "documentation" }),
|
||||
).toBeVisible();
|
||||
await expect(page.locator(".badge").filter({ hasText: "bug" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("leave a comment and reply", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"commenting",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
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 to comment" }).click();
|
||||
await page.getByPlaceholder("Reply to comment").fill("This is a reply");
|
||||
await page.getByRole("button", { name: "Comment", exact: true }).click();
|
||||
await expect(page.getByText("This is a reply")).toBeVisible();
|
||||
});
|
||||
|
||||
test("add and remove reactions", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"reactions",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).click();
|
||||
const commentReactionToggle = page.getByTitle("toggle-reaction").first();
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "👍" }).click();
|
||||
await expect(page.getByRole("button", { name: "👍 1" })).toBeVisible();
|
||||
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "🎉" }).click();
|
||||
await expect(page.getByRole("button", { name: "🎉 1" })).toBeVisible();
|
||||
await expect(page.locator(".reaction")).toHaveCount(2);
|
||||
|
||||
await page.getByRole("button", { name: "👍" }).click();
|
||||
await expect(page.locator("span").filter({ hasText: "👍 1" })).toBeHidden();
|
||||
await expect(page.locator(".reaction")).toHaveCount(1);
|
||||
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "🎉" }).first().click();
|
||||
await expect(page.getByRole("button", { name: "🎉 1" })).toBeHidden();
|
||||
await expect(page.locator(".reaction")).toHaveCount(0);
|
||||
});
|
||||
test("change patch state", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"lifecycle",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await page.getByRole("button", { name: "Archive patch" }).first().click();
|
||||
await expect(page.getByText("archived", { exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "0 patches" })).toBeVisible();
|
||||
|
||||
await page.getByLabel("stateToggle").first().click();
|
||||
await page.getByText("Convert to draft").click();
|
||||
await page.getByText("Convert to draft").click();
|
||||
await expect(page.getByText("draft", { exact: true })).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "0 patches" })).toBeVisible();
|
||||
});
|
||||
|
||||
test("patches counters", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder, defaultBranch } = await createProject(
|
||||
authenticatedPeer,
|
||||
@@ -218,114 +49,3 @@ test("patches counters", async ({ page, authenticatedPeer }) => {
|
||||
).toHaveText("2 open");
|
||||
await expect(page.locator(".list .patch-teaser")).toHaveCount(2);
|
||||
});
|
||||
|
||||
test("use revision selector", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a`);
|
||||
await page.getByRole("link", { name: "Changes" }).click();
|
||||
|
||||
// Validating the latest revision state
|
||||
await expect(
|
||||
page.getByRole("cell", { name: "Had to push a new revision" }),
|
||||
).toBeVisible();
|
||||
await page.getByRole("link", { name: "Activity" }).click();
|
||||
await expect(page.locator(".commits .teaser")).toHaveCount(2);
|
||||
await expect(page.getByRole("link", { name: "Add more text" })).toBeVisible();
|
||||
|
||||
// Open the first revision and close the latest one
|
||||
await page.getByLabel("expand").first().click();
|
||||
await page.getByLabel("expand").last().click();
|
||||
|
||||
// Validating the initial revision
|
||||
await expect(page.locator(".commits .teaser")).toHaveCount(1);
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Rewrite subtitle to README" }),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("link", { name: "Changes" }).click();
|
||||
// Switching to the initial revision
|
||||
await page.getByText("Revision 2c2f036").click();
|
||||
await expect(page.locator(".dropdown")).toBeVisible();
|
||||
await page.getByRole("link", { name: "Revision 679b2c8" }).click();
|
||||
await expect(page.locator(".dropdown")).toBeHidden();
|
||||
|
||||
await expect(
|
||||
page.getByRole("cell", { name: "Had to push a new revision" }),
|
||||
).toBeHidden();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a/679b2c84a8e15ce1f73c4c231b55431b89b2559a?tab=changes`,
|
||||
);
|
||||
});
|
||||
|
||||
test("navigate through revision diffs", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a`);
|
||||
|
||||
const firstRevision = page.locator(".revision").first();
|
||||
const secondRevision = page.locator(".revision").nth(1);
|
||||
|
||||
// Second revision
|
||||
{
|
||||
await secondRevision
|
||||
.getByRole("button", { name: "toggle-context-menu" })
|
||||
.first()
|
||||
.click();
|
||||
await secondRevision
|
||||
.getByRole("link", { name: "Compare to main: 38c225e" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 38c225..9898da" }),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a?diff=38c225e2a0b47ba59def211f4e4825c31d9463ec..9898da6155467adad511f63bf0fb5aa4156b92ef`,
|
||||
);
|
||||
await page.goBack();
|
||||
await secondRevision
|
||||
.getByRole("button", { name: "toggle-context-menu" })
|
||||
.first()
|
||||
.click();
|
||||
await secondRevision
|
||||
.getByRole("link", { name: "Compare to previous revision: 679b2c8" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 0dc373..9898da" }),
|
||||
).toBeVisible();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a?diff=0dc373db601ccbcffa80dec932e4006516709ca6..9898da6155467adad511f63bf0fb5aa4156b92ef`,
|
||||
);
|
||||
await page.goBack();
|
||||
|
||||
await secondRevision
|
||||
.getByRole("link", { name: "Compare 0dc373d..9898da6" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 0dc373..9898da" }),
|
||||
).toBeVisible();
|
||||
await page.goBack();
|
||||
}
|
||||
// First revision
|
||||
{
|
||||
await firstRevision
|
||||
.getByRole("button", { name: "toggle-context-menu" })
|
||||
.first()
|
||||
.click();
|
||||
await firstRevision
|
||||
.getByRole("link", { name: "Compare to main: 38c225e" })
|
||||
.click();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Compare 38c225..0dc373" }),
|
||||
).toBeVisible();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a?diff=38c225e2a0b47ba59def211f4e4825c31d9463ec..0dc373db601ccbcffa80dec932e4006516709ca6`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test("view file navigation from changes tab", async ({ page }) => {
|
||||
await page.goto(`${cobUrl}/patches/679b2c84a8e15ce1f73c4c231b55431b89b2559a`);
|
||||
await page.getByRole("button", { name: "Changes" }).click();
|
||||
await page.getByRole("button", { name: "View file" }).click();
|
||||
await expect(page).toHaveURL(
|
||||
`${cobUrl}/tree/9898da6155467adad511f63bf0fb5aa4156b92ef/README.md`,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import { test } from "@tests/support/fixtures.js";
|
||||
import {
|
||||
createProject,
|
||||
expectReactionsToWork,
|
||||
expectThreadCommentingToWork,
|
||||
extractPatchId,
|
||||
} from "@tests/support/project";
|
||||
|
||||
test("leave comments and replies", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"commenting",
|
||||
);
|
||||
await authenticatedPeer.rad(
|
||||
[
|
||||
"issue",
|
||||
"open",
|
||||
"--title",
|
||||
"This is an issue to write comments and replies",
|
||||
"--description",
|
||||
"We'll give it a few comments and replies.",
|
||||
],
|
||||
{ cwd: projectFolder },
|
||||
);
|
||||
await page.goto(
|
||||
`${authenticatedPeer.uiUrl()}/${rid}/issues/017f0c6827fb19e4cfd5103e452ba58665f01798`,
|
||||
);
|
||||
await expectThreadCommentingToWork(page);
|
||||
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await expectThreadCommentingToWork(page);
|
||||
});
|
||||
|
||||
test("add and remove reactions", async ({ page, authenticatedPeer }) => {
|
||||
const { rid, projectFolder } = await createProject(
|
||||
authenticatedPeer,
|
||||
"reactions",
|
||||
);
|
||||
await authenticatedPeer.git(["switch", "-c", "feature-1"], {
|
||||
cwd: projectFolder,
|
||||
});
|
||||
await authenticatedPeer.git(
|
||||
["commit", "--allow-empty", "-m", "Some patch title"],
|
||||
{
|
||||
cwd: projectFolder,
|
||||
},
|
||||
);
|
||||
const patchId = extractPatchId(
|
||||
await authenticatedPeer.git(["push", "rad", "HEAD:refs/patches"], {
|
||||
cwd: projectFolder,
|
||||
}),
|
||||
);
|
||||
await page.goto(`${authenticatedPeer.uiUrl()}/${rid}/patches/${patchId}`);
|
||||
await expectReactionsToWork(page);
|
||||
});
|
||||
@@ -1,6 +1,10 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import type { RadiclePeer } from "@tests/support/peerManager";
|
||||
import type { ExecaReturnValue } from "execa";
|
||||
|
||||
import * as Path from "node:path";
|
||||
import { expect } from "@playwright/test";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
// Create a project using the rad CLI.
|
||||
export async function createProject(
|
||||
@@ -39,3 +43,141 @@ export async function createProject(
|
||||
|
||||
return { rid, projectFolder, defaultBranch };
|
||||
}
|
||||
|
||||
export function extractPatchId(cmdOutput: ExecaReturnValue<string>) {
|
||||
const match = cmdOutput.stderr.match(/[0-9a-f]{40}/);
|
||||
if (match) {
|
||||
return match[0];
|
||||
} else {
|
||||
throw new Error("Could not get patch id");
|
||||
}
|
||||
}
|
||||
|
||||
export async function expectThreadCommentingToWork(page: Page) {
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).click();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "Comment", exact: true }),
|
||||
).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByText("This is a comment")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit comment" }).first().click();
|
||||
await page
|
||||
.getByPlaceholder("Leave your comment")
|
||||
.fill("This is an edited comment");
|
||||
await page.getByRole("button", { name: "Save" }).click();
|
||||
await expect(page.getByRole("button", { name: "Save" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByText("This is an edited comment")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Reply to comment" }).click();
|
||||
await page.getByPlaceholder("Reply to comment").fill("This is a reply");
|
||||
await page.getByRole("button", { name: "Comment", exact: true }).click();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "Comment", exact: true }),
|
||||
).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByText("This is a reply")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit comment" }).nth(1).click();
|
||||
await page
|
||||
.getByPlaceholder("Leave your comment")
|
||||
.fill("This is an edited reply");
|
||||
await page.getByRole("button", { name: "Save" }).click();
|
||||
await expect(page.getByRole("button", { name: "Save" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByText("This is an edited reply")).toBeVisible();
|
||||
}
|
||||
|
||||
export async function expectLabelEditingToWork(page: Page) {
|
||||
await expect(page.getByText("No labels")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit labels" }).click();
|
||||
await page.getByPlaceholder("Add label").fill("bug");
|
||||
await page.getByRole("button", { name: "dismiss changes" }).click();
|
||||
await expect(page.getByText("No labels")).toBeVisible();
|
||||
await page.getByRole("button", { name: "edit labels" }).click();
|
||||
await expect(page.getByPlaceholder("Add label")).toHaveValue("");
|
||||
|
||||
await page.getByPlaceholder("Add label").fill("bug");
|
||||
await page.keyboard.press("Enter");
|
||||
await page.getByPlaceholder("Add label").fill("bug");
|
||||
await expect(page.getByText("This label is already added")).toBeVisible();
|
||||
await page.getByPlaceholder("Add label").clear();
|
||||
await expect(page.getByText("This label is already added")).toBeHidden();
|
||||
|
||||
await page.getByPlaceholder("Add label").fill("documentation");
|
||||
await page.keyboard.press("Enter");
|
||||
await page.getByRole("button", { name: "save labels" }).click();
|
||||
await expect(page.getByRole("button", { name: "save labels" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: "bug" })).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("button", { name: "documentation" }),
|
||||
).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "edit labels" }).click();
|
||||
await page
|
||||
.locator("span")
|
||||
.filter({ hasText: "documentation" })
|
||||
.getByTitle("remove label")
|
||||
.click();
|
||||
await page.getByRole("button", { name: "save labels" }).click();
|
||||
await expect(page.getByRole("button", { name: "save labels" })).toBeHidden();
|
||||
await page.reload();
|
||||
await expect(page.getByRole("button", { name: "bug" })).toBeVisible();
|
||||
}
|
||||
|
||||
export async function expectReactionsToWork(page: Page) {
|
||||
await page.getByRole("button", { name: "Leave your comment" }).click();
|
||||
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
|
||||
await page.getByRole("button", { name: "Comment" }).click();
|
||||
const commentReactionToggle = page.getByTitle("toggle-reaction").first();
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "👍" }).click();
|
||||
await expect(page.getByRole("button", { name: "👍 1" })).toBeVisible();
|
||||
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "🎉" }).click();
|
||||
await expect(page.getByRole("button", { name: "🎉 1" })).toBeVisible();
|
||||
await expect(page.locator(".reaction")).toHaveCount(2);
|
||||
|
||||
await page.getByRole("button", { name: "👍" }).click();
|
||||
await expect(page.locator("span").filter({ hasText: "👍 1" })).toBeHidden();
|
||||
await expect(page.locator(".reaction")).toHaveCount(1);
|
||||
|
||||
await commentReactionToggle.click();
|
||||
await page.getByRole("button", { name: "🎉" }).first().click();
|
||||
await expect(page.getByRole("button", { name: "🎉 1" })).toBeHidden();
|
||||
await expect(page.locator(".reaction")).toHaveCount(0);
|
||||
}
|
||||
|
||||
export async function addEmbed(
|
||||
page: Page,
|
||||
url: string,
|
||||
fileName: string,
|
||||
fileType: string,
|
||||
) {
|
||||
const buffer = readFileSync(url).toString("base64");
|
||||
const dataTransfer = await page.evaluateHandle(
|
||||
({ buffer, localFileName, localFileType }) => {
|
||||
const arrayBuffer = Uint8Array.from(atob(buffer), c => c.charCodeAt(0));
|
||||
const dt = new DataTransfer();
|
||||
const file = new File([arrayBuffer.buffer], localFileName, {
|
||||
type: localFileType,
|
||||
});
|
||||
dt.items.add(file);
|
||||
return dt;
|
||||
},
|
||||
{
|
||||
buffer,
|
||||
localFileName: fileName,
|
||||
localFileType: fileType,
|
||||
},
|
||||
);
|
||||
await page.dispatchEvent("textarea[aria-label=textarea-comment]", "drop", {
|
||||
dataTransfer,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user