Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

chore(site): add e2e tests for groups#12866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
BrunoQuaresma merged 11 commits intomainfrombq/add-e2e-for-create-and-remove-groups
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletionssite/e2e/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
import type { Page } from "@playwright/test";
import * as API from "api/api";
import { coderPort } from "./constants";
import { findSessionToken, randomName } from "./helpers";

let currentOrgId: string;

export const setupApiCalls = async (page: Page) => {
const token = await findSessionToken(page);
API.setSessionToken(token);
API.setHost(`http://127.0.0.1:${coderPort}`);
};

export const getCurrentOrgId = async (): Promise<string> => {
if (currentOrgId) {
return currentOrgId;
}
const currentUser = await API.getAuthenticatedUser();
currentOrgId = currentUser.organization_ids[0];
return currentOrgId;
};

export const createUser = async (orgId: string) => {
const name = randomName();
const user = await API.createUser({
email: `${name}@coder.com`,
username: name,
password: "s3cure&password!",
login_type: "password",
disable_login: false,
organization_id: orgId,
});
return user;
};

export const createGroup = async (orgId: string) => {
const name = randomName();
const group = await API.createGroup(orgId, {
name,
display_name: `Display ${name}`,
avatar_url: "/emojis/1f60d.png",
quota_allowance: 0,
});
return group;
};
7 changes: 0 additions & 7 deletionssite/e2e/helpers.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,7 +7,6 @@ import capitalize from "lodash/capitalize";
import path from "path";
import * as ssh from "ssh2";
import { Duplex } from "stream";
import * as API from "api/api";
import type {
WorkspaceBuildParameter,
UpdateTemplateMeta,
Expand DownExpand Up@@ -826,9 +825,3 @@ export async function openTerminalWindow(

return terminal;
}

export const setupApiCalls = async (page: Page) => {
const token = await findSessionToken(page);
API.setSessionToken(token);
API.setHost(`http://127.0.0.1:${coderPort}`);
};
34 changes: 34 additions & 0 deletionssite/e2e/tests/groups/addMembers.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
import { test, expect } from "@playwright/test";
import {
createGroup,
createUser,
getCurrentOrgId,
setupApiCalls,
} from "../../api";
import { requiresEnterpriseLicense } from "../../helpers";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

test("add members", async ({ page, baseURL }) => {
requiresEnterpriseLicense();
await setupApiCalls(page);
const orgId = await getCurrentOrgId();
const group = await createGroup(orgId);
const numberOfMembers = 3;
const users = await Promise.all(
Array.from({ length: numberOfMembers }, () => createUser(orgId)),
);

await page.goto(`${baseURL}/groups/${group.id}`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveTitle(`${group.display_name} - Coder`);

for (const user of users) {
await page.getByPlaceholder("User email or username").fill(user.username);
await page.getByRole("option", { name: user.email }).click();
await page.getByRole("button", { name: "Add user" }).click();
await expect(page.getByRole("row", { name: user.username })).toBeVisible();
}
});
32 changes: 32 additions & 0 deletionssite/e2e/tests/groups/addUsersToDefaultGroup.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
import { test, expect } from "@playwright/test";
import { createUser, getCurrentOrgId, setupApiCalls } from "../../api";
import { requiresEnterpriseLicense } from "../../helpers";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

const DEFAULT_GROUP_NAME = "Everyone";

test(`Every user should be automatically added to the default '${DEFAULT_GROUP_NAME}' group upon creation`, async ({
page,
baseURL,
}) => {
requiresEnterpriseLicense();
await setupApiCalls(page);
const orgId = await getCurrentOrgId();
const numberOfMembers = 3;
const users = await Promise.all(
Array.from({ length: numberOfMembers }, () => createUser(orgId)),
);

await page.goto(`${baseURL}/groups`, { waitUntil: "domcontentloaded" });
await expect(page).toHaveTitle("Groups - Coder");

const groupRow = page.getByRole("row", { name: DEFAULT_GROUP_NAME });
await groupRow.click();
await expect(page).toHaveTitle(`${DEFAULT_GROUP_NAME} - Coder`);

for (const user of users) {
await expect(page.getByRole("row", { name: user.username })).toBeVisible();
}
});
30 changes: 30 additions & 0 deletionssite/e2e/tests/groups/createGroup.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
import { test, expect } from "@playwright/test";
import { randomName, requiresEnterpriseLicense } from "../../helpers";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

test("create group", async ({ page, baseURL }) => {
requiresEnterpriseLicense();
await page.goto(`${baseURL}/groups`, { waitUntil: "domcontentloaded" });
await expect(page).toHaveTitle("Groups - Coder");

await page.getByText("Create group").click();
await expect(page).toHaveTitle("Create Group - Coder");

const name = randomName();
const groupValues = {
name: name,
displayName: `Display Name for ${name}`,
avatarURL: "/emojis/1f60d.png",
};

await page.getByLabel("Name", { exact: true }).fill(groupValues.name);
await page.getByLabel("Display Name").fill(groupValues.displayName);
await page.getByLabel("Avatar URL").fill(groupValues.avatarURL);
await page.getByRole("button", { name: "Submit" }).click();

await expect(page).toHaveTitle(`${groupValues.displayName} - Coder`);
await expect(page.getByText(groupValues.displayName)).toBeVisible();
await expect(page.getByText("No members yet")).toBeVisible();
});
23 changes: 23 additions & 0 deletionssite/e2e/tests/groups/navigateToGroupPage.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
import { test, expect } from "@playwright/test";
import { createGroup, getCurrentOrgId, setupApiCalls } from "../../api";
import { requiresEnterpriseLicense } from "../../helpers";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

test("navigate to group page", async ({ page, baseURL }) => {
requiresEnterpriseLicense();
await setupApiCalls(page);
const orgId = await getCurrentOrgId();
const group = await createGroup(orgId);

await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" });
await expect(page).toHaveTitle("Users - Coder");

await page.getByRole("link", { name: "Groups" }).click();
await expect(page).toHaveTitle("Groups - Coder");

const groupRow = page.getByRole("row", { name: group.display_name });
await groupRow.click();
await expect(page).toHaveTitle(`${group.display_name} - Coder`);
});
26 changes: 26 additions & 0 deletionssite/e2e/tests/groups/removeGroup.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
import { test, expect } from "@playwright/test";
import { createGroup, getCurrentOrgId, setupApiCalls } from "../../api";
import { requiresEnterpriseLicense } from "../../helpers";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

test("remove group", async ({ page, baseURL }) => {
requiresEnterpriseLicense();
await setupApiCalls(page);
const orgId = await getCurrentOrgId();
const group = await createGroup(orgId);

await page.goto(`${baseURL}/groups/${group.id}`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveTitle(`${group.display_name} - Coder`);

await page.getByRole("button", { name: "Delete" }).click();
const dialog = page.getByTestId("dialog");
await dialog.getByLabel("Name of the group to delete").fill(group.name);
await dialog.getByRole("button", { name: "Delete" }).click();
await expect(page.getByText("Group deleted successfully.")).toBeVisible();

await expect(page).toHaveTitle("Groups - Coder");
});
36 changes: 36 additions & 0 deletionssite/e2e/tests/groups/removeMember.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
import { test, expect } from "@playwright/test";
import * as API from "api/api";
import {
createGroup,
createUser,
getCurrentOrgId,
setupApiCalls,
} from "../../api";
import { requiresEnterpriseLicense } from "../../helpers";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

test("remove member", async ({ page, baseURL }) => {
requiresEnterpriseLicense();
await setupApiCalls(page);
const orgId = await getCurrentOrgId();
const [group, member] = await Promise.all([
createGroup(orgId),
createUser(orgId),
]);
await API.addMember(group.id, member.id);

await page.goto(`${baseURL}/groups/${group.id}`, {
waitUntil: "domcontentloaded",
});
await expect(page).toHaveTitle(`${group.display_name} - Coder`);

const userRow = page.getByRole("row", { name: member.username });
await userRow.getByRole("button", { name: "More options" }).click();

const menu = page.locator("#more-options");
await menu.getByText("Remove").click({ timeout: 1_000 });

await expect(page.getByText("Member removed successfully.")).toBeVisible();
});
20 changes: 6 additions & 14 deletionssite/e2e/tests/users/removeUser.spec.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
import { test, expect } from "@playwright/test";
import * as API from "api/api";
import { randomName, setupApiCalls } from "../../helpers";
import { createUser, getCurrentOrgId, setupApiCalls } from "../../api";
import { beforeCoderTest } from "../../hooks";

test.beforeEach(async ({ page }) => await beforeCoderTest(page));

test("remove user", async ({ page, baseURL }) => {
await setupApiCalls(page);
const currentUser = await API.getAuthenticatedUser();
const name = randomName();
const user = await API.createUser({
email: `${name}@coder.com`,
username: name,
password: "s3cure&password!",
login_type: "password",
disable_login: false,
organization_id: currentUser.organization_ids[0],
});
const orgId = await getCurrentOrgId();
const user = await createUser(orgId);

await page.goto(`${baseURL}/users`, { waitUntil: "domcontentloaded" });
await expect(page).toHaveTitle("Users - Coder");

const userRow = page.locator("tr", {hasText: user.email });
const userRow = page.getByRole("row", {name: user.email });
await userRow.getByRole("button", { name: "More options" }).click();
await userRow.getByText("Delete", { exact: false }).click();
const menu = page.locator("#more-options");
await menu.getByText("Delete").click();

const dialog = page.getByTestId("dialog");
await dialog.getByLabel("Name of the user to delete").fill(user.username);
Expand Down
1 change: 0 additions & 1 deletionsite/src/api/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1147,7 +1147,6 @@ export const patchGroup = async (
export const addMember = async (groupId: string, userId: string) => {
return patchGroup(groupId, {
name: "",
display_name: "",
add_users: [userId],
remove_users: [],
});
Expand Down
1 change: 1 addition & 0 deletionssite/src/pages/GroupsPage/GroupPage.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -197,6 +197,7 @@ export const GroupPage: FC = () => {
onConfirm={async () => {
try {
await deleteGroupMutation.mutateAsync(groupId);
displaySuccess("Group deleted successfully.");
navigate("/groups");
} catch (error) {
displayError(getErrorMessage(error, "Failed to delete group."));
Expand Down
11 changes: 7 additions & 4 deletionssite/src/pages/UsersPage/UsersLayout.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
import GroupAdd from "@mui/icons-material/GroupAddOutlined";
import PersonAdd from "@mui/icons-material/PersonAddOutlined";
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import { type FC, Suspense } from "react";
import {
Link as RouterLink,
Expand DownExpand Up@@ -43,9 +42,13 @@ export const UsersLayout: FC = () => {
</Button>
)}
{canCreateGroup && isTemplateRBACEnabled && (
<Link component={RouterLink} to="/groups/create">
<Button startIcon={<GroupAdd />}>Create group</Button>
</Link>
<Button
component={RouterLink}
startIcon={<GroupAdd />}
to="/groups/create"
>
Create group
</Button>
)}
</>
}
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp