Files
authentik/web/test/browser/groups.test.ts
T
Teffen Ellis b88d082947 web/a11y: Modals, Command Palette (Merge branch) (#17812)
* Use project relative paths.

* Fix tests.

* Fix types.

* Clean up admin imports.

* Move admin import.

* Remove or replace references to admin.

* Typo fix.

* Flesh out ak-modal, about modal.

* Flesh out lazy modal.

* Fix portal elements not using dialog scope.

* Fix url parameters, wizards.

* Fix invokers, lazy load.

* Fix theming.

* Add placeholders, help.

* Flesh out command palette.

Flesh out styles, command invokers.

Continue clean up.

Allow slotted content.

Flesh out.

* Flesh out edit invoker. Prep groups.

* Fix odd labeling, legacy situations.

* Prepare deprecation of table modal. Clean up serialization.

* Tidy types.

* Port provider select modal.

* Port member select form.

* Flesh out role modal. Fix loading state.

* Port user group form.

* Fix spellcheck.

* Fix dialog detection.

* Revise types.

* Port rac launch modal.

* Remove deprecated table modal.

* Consistent form action placement.

* Consistent casing.

* Consistent alignment.

* Use more appropriate description.

* Flesh out icon. Fix alignment, colors.

* Flesh out user search.

* Consistent save button.

* Clean up labels.

* Reduce warning noise.

* Clean up label.

* Use attribute e2e expects.

* Use directive. Fix lifecycle

* Fix frequent un-memoized entries.

* Fix up closedBy detection.

* Tidy alignment.

* Fix types, composition.

* Fix labels, tests.

* Fix up impersonation, labels.

* Flesh out. Fix refresh after submit.

* Flesh out basic modal test.

* Fix ARIA.

* Flesh out roles test.

* Revise selectors.

* Clean up selectors.

* Fix impersonation labels, form references.

* Fix messages appearing under modals.

* Ensure reason is parsed.

* Flesh out impersonation test.

* Flesh out impersonate test.

* Flesh out application tests. Clean up toolbar header, ARIA.

* Flesh out wizard test.

* Refine weight, order.

* Fix up initial values, selectors.

* Fix tests.

* Fix selector.
2026-03-25 06:07:29 +00:00

180 lines
6.3 KiB
TypeScript

import { expect, test } from "#e2e";
import { randomName } from "#e2e/utils/generators";
import { IDGenerator } from "@goauthentik/core/id";
import { series } from "@goauthentik/core/promises";
import { snakeCase } from "change-case";
test.describe("Groups", () => {
const adminGroupName = "authentik Admins";
const adminUsername = "akadmin";
const usernames = new Map<string, string>();
const groupNames = new Map<string, string>();
//#region Lifecycle
test.beforeEach("Prepare user", async ({ session }, { testId }) => {
const seed = IDGenerator.randomID(6);
const groupName = `${randomName(seed)} (${seed})`;
groupNames.set(testId, groupName);
usernames.set(testId, snakeCase(groupName));
await test.step("Authenticate", async () => {
await session.login({
to: "/if/admin/#/identity/groups",
});
});
});
//#endregion
//#region Tests
test("Creating a user within the admin group", async ({
navigator,
form,
pointer,
page,
}, testInfo) => {
const { fill, search } = form;
const { click } = pointer;
const displayName = groupNames.get(testInfo.testId)!;
const username = usernames.get(testInfo.testId)!;
const adminsURL = await test.step("Find admin group via search", async () => {
const $adminGroupRow = await search(adminGroupName);
await expect($adminGroupRow, "Admin group is visible").toBeVisible();
const groupLink = $adminGroupRow.getByRole("link", { name: "view details" });
await expect(groupLink, "Admin group link is visible").toBeVisible();
return groupLink.evaluate((el: HTMLAnchorElement) => el.href);
});
expect(adminsURL, "Admin group link has href").not.toBeNull();
await navigator.navigate(adminsURL);
await test.step("User creation", async () => {
await click("Users", "tab");
const dialog = page.getByRole("dialog", { name: "New Group User" });
await expect(dialog, "Dialog is initially closed").toBeHidden();
await click("Add New User", "button");
await click("New Group User...", "menuitem");
await expect(dialog, "Dialog opens").toBeVisible();
await series(
[fill, /^Username/, username, dialog],
[fill, /^Display Name/, displayName, dialog],
[fill, /^Email Address/, `${username}@example.com`, dialog],
);
await dialog.getByRole("button", { name: "Create User" }).click();
await dialog.waitFor({ state: "hidden" });
await expect(dialog, "Dialog closes after creating user").toBeHidden();
});
await test.step("Verify user creation", async () => {
const $user = await test.step("Find user via search", () => {
const context = page.getByRole("tabpanel", { name: "Users" });
return search(username, context);
});
await expect($user, "User is visible").toBeVisible();
});
});
test("Simple group", async ({ form, pointer, page }, testInfo) => {
const groupName = groupNames.get(testInfo.testId)!;
const { fill, search } = form;
const { click } = pointer;
const dialog = page.getByRole("dialog", { name: "New Group" });
await test.step("Group Creation", async () => {
await expect(dialog, "Dialog is initially closed").toBeHidden();
await click("New Group", "button");
await expect(dialog, "Dialog opens").toBeVisible();
await series(
// ---
[fill, /^Group Name/, groupName, dialog],
);
const createButton = dialog.getByRole("button", { name: "Create Group" });
await expect(createButton, "Create button is visible").toBeVisible();
await createButton.evaluate((element: HTMLButtonElement) => element.click());
await expect(dialog, "Dialog closes after creating group").toBeHidden();
});
await test.step("Verify group creation", async () => {
const groupRow = await test.step("Find group via search", () => search(groupName));
await expect(groupRow, "Group is visible").toBeVisible();
await groupRow.getByRole("link", { name: "view details" }).click();
});
await test.step("Assigning a user to the group", async () => {
const assignUsersModal = page.getByRole("dialog", { name: "Assign Additional Users" });
const selectUsersModal = page.getByRole("dialog", { name: "Select users" });
await series(
// ---
[click, "users", "tab"],
[click, "Add existing user", "button"],
[click, "Open user selection dialog", "button"],
);
const adminRow = await test.step("Find admin via search", () =>
search(adminUsername, selectUsersModal));
await expect(adminRow, "Admin is visible").toBeVisible();
await adminRow.getByRole("checkbox").check();
const confirmButton = selectUsersModal.getByRole("button", { name: "Confirm" });
await expect(confirmButton, "Confirm button is visible").toBeVisible();
await confirmButton.evaluate((element: HTMLButtonElement) => element.click());
const assignButton = assignUsersModal.getByRole("button", { name: "Assign" });
await expect(assignButton, "Assign button is visible").toBeVisible();
await assignButton.evaluate((element: HTMLButtonElement) => element.click());
await expect(assignUsersModal, "Assign users modal closes").toBeHidden();
await test.step("Verify admin user assignment", async () => {
// eslint-disable-next-line max-nested-callbacks
const groupRow = await test.step("Find group via search", () => {
const context = page.getByRole("tabpanel", { name: "Users" });
return search(adminUsername, context);
});
await expect(groupRow, "Group is visible").toBeVisible();
});
});
});
//#endregion
});