mirror of
https://github.com/coder/coder.git
synced 2025-07-18 14:17:22 +00:00
feat: create e2e tests for organization custom roles page (#15814)
Adds 5 premium tests and 1 non-premium test.
This commit is contained in:
@ -93,6 +93,43 @@ export const createOrganizationSyncSettings = async () => {
|
||||
return settings;
|
||||
};
|
||||
|
||||
export const createCustomRole = async (
|
||||
orgId: string,
|
||||
name: string,
|
||||
displayName: string,
|
||||
) => {
|
||||
const role = await API.createOrganizationRole(orgId, {
|
||||
name,
|
||||
display_name: displayName,
|
||||
organization_id: orgId,
|
||||
site_permissions: [],
|
||||
organization_permissions: [
|
||||
{
|
||||
negate: false,
|
||||
resource_type: "organization_member",
|
||||
action: "create",
|
||||
},
|
||||
{
|
||||
negate: false,
|
||||
resource_type: "organization_member",
|
||||
action: "delete",
|
||||
},
|
||||
{
|
||||
negate: false,
|
||||
resource_type: "organization_member",
|
||||
action: "read",
|
||||
},
|
||||
{
|
||||
negate: false,
|
||||
resource_type: "organization_member",
|
||||
action: "update",
|
||||
},
|
||||
],
|
||||
user_permissions: [],
|
||||
});
|
||||
return role;
|
||||
};
|
||||
|
||||
export async function verifyConfigFlagBoolean(
|
||||
page: Page,
|
||||
config: DeploymentConfig,
|
||||
|
@ -49,6 +49,10 @@ export function requiresLicense() {
|
||||
test.skip(!license);
|
||||
}
|
||||
|
||||
export function requiresUnlicensed() {
|
||||
test.skip(license.length > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* requireTerraformProvisioner by default is enabled.
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
deleteOrganization,
|
||||
setupApiCalls,
|
||||
} from "../../api";
|
||||
import { requiresLicense } from "../../helpers";
|
||||
import { randomName, requiresLicense } from "../../helpers";
|
||||
import { beforeCoderTest } from "../../hooks";
|
||||
|
||||
test.describe("IdpOrgSyncPage", () => {
|
||||
@ -123,7 +123,9 @@ test.describe("IdpOrgSyncPage", () => {
|
||||
requiresLicense();
|
||||
await setupApiCalls(page);
|
||||
|
||||
await createOrganizationWithName("developers");
|
||||
const orgName = randomName();
|
||||
|
||||
await createOrganizationWithName(orgName);
|
||||
|
||||
await page.goto("/deployment/idp-org-sync", {
|
||||
waitUntil: "domcontentloaded",
|
||||
@ -141,7 +143,7 @@ test.describe("IdpOrgSyncPage", () => {
|
||||
|
||||
// Select Coder organization from combobox
|
||||
await orgSelector.click();
|
||||
await page.getByRole("option", { name: "developers" }).click();
|
||||
await page.getByRole("option", { name: orgName }).click();
|
||||
|
||||
// Add button should now be enabled
|
||||
await expect(addButton).toBeEnabled();
|
||||
@ -152,12 +154,12 @@ test.describe("IdpOrgSyncPage", () => {
|
||||
const newRow = page.getByTestId("idp-org-new-idp-org");
|
||||
await expect(newRow).toBeVisible();
|
||||
await expect(newRow.getByText("new-idp-org")).toBeVisible();
|
||||
await expect(newRow.getByText("developers")).toBeVisible();
|
||||
await expect(newRow.getByText(orgName)).toBeVisible();
|
||||
|
||||
await expect(
|
||||
page.getByText("Organization sync settings updated."),
|
||||
).toBeVisible();
|
||||
|
||||
await deleteOrganization("developers");
|
||||
await deleteOrganization(orgName);
|
||||
});
|
||||
});
|
||||
|
205
site/e2e/tests/organizations/customRoles/customRoles.spec.ts
Normal file
205
site/e2e/tests/organizations/customRoles/customRoles.spec.ts
Normal file
@ -0,0 +1,205 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import {
|
||||
createCustomRole,
|
||||
createOrganizationWithName,
|
||||
deleteOrganization,
|
||||
setupApiCalls,
|
||||
} from "../../../api";
|
||||
import {
|
||||
randomName,
|
||||
requiresLicense,
|
||||
requiresUnlicensed,
|
||||
} from "../../../helpers";
|
||||
import { beforeCoderTest } from "../../../hooks";
|
||||
|
||||
test.describe("CustomRolesPage", () => {
|
||||
test.beforeEach(async ({ page }) => await beforeCoderTest(page));
|
||||
|
||||
test("create custom role and cancel edit changes", async ({ page }) => {
|
||||
requiresLicense();
|
||||
await setupApiCalls(page);
|
||||
|
||||
const org = await createOrganizationWithName(randomName());
|
||||
|
||||
const customRole = await createCustomRole(
|
||||
org.id,
|
||||
"custom-role-test-1",
|
||||
"Custom Role Test 1",
|
||||
);
|
||||
|
||||
await page.goto(`/organizations/${org.name}/roles`);
|
||||
const roleRow = page.getByTestId(`role-${customRole.name}`);
|
||||
await expect(roleRow.getByText(customRole.display_name)).toBeVisible();
|
||||
await expect(roleRow.getByText("organization_member")).toBeVisible();
|
||||
|
||||
await roleRow.getByRole("button", { name: "More options" }).click();
|
||||
const menu = page.locator("#more-options");
|
||||
await menu.getByText("Edit").click();
|
||||
|
||||
await expect(page).toHaveURL(
|
||||
`/organizations/${org.name}/roles/${customRole.name}`,
|
||||
);
|
||||
|
||||
const cancelButton = page.getByRole("button", { name: "Cancel" }).first();
|
||||
await expect(cancelButton).toBeVisible();
|
||||
await cancelButton.click();
|
||||
|
||||
await expect(page).toHaveURL(`/organizations/${org.name}/roles`);
|
||||
|
||||
await deleteOrganization(org.name);
|
||||
});
|
||||
|
||||
test("create custom role, edit role and save changes", async ({ page }) => {
|
||||
requiresLicense();
|
||||
await setupApiCalls(page);
|
||||
|
||||
const org = await createOrganizationWithName(randomName());
|
||||
|
||||
const customRole = await createCustomRole(
|
||||
org.id,
|
||||
"custom-role-test-1",
|
||||
"Custom Role Test 1",
|
||||
);
|
||||
|
||||
await page.goto(`/organizations/${org.name}/roles`);
|
||||
const roleRow = page.getByTestId(`role-${customRole.name}`);
|
||||
await expect(roleRow.getByText(customRole.display_name)).toBeVisible();
|
||||
await expect(roleRow.getByText("organization_member")).toBeVisible();
|
||||
|
||||
await page.goto(`/organizations/${org.name}/roles/${customRole.name}`);
|
||||
|
||||
const displayNameInput = page.getByRole("textbox", {
|
||||
name: "Display name",
|
||||
});
|
||||
await displayNameInput.fill("Custom Role Test 2 Edited");
|
||||
|
||||
const groupCheckbox = page.getByTestId("group").getByRole("checkbox");
|
||||
await expect(groupCheckbox).toBeVisible();
|
||||
await groupCheckbox.click();
|
||||
|
||||
const organizationMemberCheckbox = page
|
||||
.getByTestId("organization_member")
|
||||
.getByRole("checkbox");
|
||||
await expect(organizationMemberCheckbox).toBeVisible();
|
||||
await organizationMemberCheckbox.click();
|
||||
|
||||
const saveButton = page.getByRole("button", { name: "Save" }).first();
|
||||
await expect(saveButton).toBeVisible();
|
||||
await saveButton.click();
|
||||
|
||||
await expect(roleRow.getByText("Custom Role Test 2 Edited")).toBeVisible();
|
||||
|
||||
const roleRow2 = page.getByTestId(`role-${customRole.name}`);
|
||||
await expect(roleRow2.getByText("organization_member")).not.toBeVisible();
|
||||
await expect(roleRow2.getByText("group")).toBeVisible();
|
||||
|
||||
await expect(page).toHaveURL(`/organizations/${org.name}/roles`);
|
||||
|
||||
await deleteOrganization(org.name);
|
||||
});
|
||||
|
||||
test("displays built-in role without edit/delete options", async ({
|
||||
page,
|
||||
}) => {
|
||||
requiresLicense();
|
||||
await setupApiCalls(page);
|
||||
|
||||
const org = await createOrganizationWithName(randomName());
|
||||
|
||||
await page.goto(`/organizations/${org.name}/roles`);
|
||||
|
||||
const roleRow = page.getByTestId("role-organization-admin");
|
||||
await expect(roleRow).toBeVisible();
|
||||
|
||||
await expect(roleRow.getByText("Organization Admin")).toBeVisible();
|
||||
|
||||
// Verify that the more menu (three dots) is not present for built-in roles
|
||||
await expect(
|
||||
roleRow.getByRole("button", { name: "More options" }),
|
||||
).not.toBeVisible();
|
||||
|
||||
await deleteOrganization(org.name);
|
||||
});
|
||||
|
||||
test("create custom role with UI", async ({ page }) => {
|
||||
requiresLicense();
|
||||
await setupApiCalls(page);
|
||||
|
||||
const org = await createOrganizationWithName(randomName());
|
||||
|
||||
await page.goto(`/organizations/${org.name}/roles`);
|
||||
|
||||
await page
|
||||
.getByRole("link", { name: "Create custom role" })
|
||||
.first()
|
||||
.click();
|
||||
|
||||
await expect(page).toHaveURL(`/organizations/${org.name}/roles/create`);
|
||||
|
||||
const customRoleName = "custom-role-test";
|
||||
const roleNameInput = page.getByRole("textbox", {
|
||||
exact: true,
|
||||
name: "Name",
|
||||
});
|
||||
await roleNameInput.fill(customRoleName);
|
||||
|
||||
const customRoleDisplayName = "Custom Role Test";
|
||||
const displayNameInput = page.getByRole("textbox", {
|
||||
exact: true,
|
||||
name: "Display Name",
|
||||
});
|
||||
await displayNameInput.fill(customRoleDisplayName);
|
||||
|
||||
await page.getByRole("button", { name: "Create Role" }).first().click();
|
||||
|
||||
await expect(page).toHaveURL(`/organizations/${org.name}/roles`);
|
||||
|
||||
const roleRow = page.getByTestId(`role-${customRoleName}`);
|
||||
await expect(roleRow.getByText(customRoleDisplayName)).toBeVisible();
|
||||
await expect(roleRow.getByText("None")).toBeVisible();
|
||||
|
||||
await deleteOrganization(org.name);
|
||||
});
|
||||
|
||||
test("delete custom role", async ({ page }) => {
|
||||
requiresLicense();
|
||||
await setupApiCalls(page);
|
||||
|
||||
const org = await createOrganizationWithName(randomName());
|
||||
const customRole = await createCustomRole(
|
||||
org.id,
|
||||
"custom-role-test-1",
|
||||
"Custom Role Test 1",
|
||||
);
|
||||
await page.goto(`/organizations/${org.name}/roles`);
|
||||
|
||||
const roleRow = page.getByTestId(`role-${customRole.name}`);
|
||||
await roleRow.getByRole("button", { name: "More options" }).click();
|
||||
|
||||
const menu = page.locator("#more-options");
|
||||
await menu.getByText("Delete…").click();
|
||||
|
||||
const input = page.getByRole("textbox");
|
||||
await input.fill(customRole.name);
|
||||
await page.getByRole("button", { name: "Delete" }).click();
|
||||
|
||||
await expect(
|
||||
page.getByText("Custom role deleted successfully!"),
|
||||
).toBeVisible();
|
||||
|
||||
await deleteOrganization(org.name);
|
||||
});
|
||||
});
|
||||
|
||||
test("custom roles disabled", async ({ page }) => {
|
||||
requiresUnlicensed();
|
||||
await page.goto("/organizations/coder/roles");
|
||||
await expect(page).toHaveURL("/organizations/coder/roles");
|
||||
|
||||
await expect(
|
||||
page.getByText("Upgrade to a premium license to create a custom role"),
|
||||
).toBeVisible();
|
||||
await expect(
|
||||
page.getByRole("link", { name: "Create custom role" }),
|
||||
).not.toBeVisible();
|
||||
});
|
Reference in New Issue
Block a user