keycloak-scim/js/apps/account-ui/test/account-security/linked-accounts.spec.ts
Jon Koops a0c99a7ae0
Show full error details in admin and account consoles
Closes #30705

Signed-off-by: Jon Koops <jonkoops@gmail.com>
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
Co-authored-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
2024-07-10 16:20:26 +02:00

124 lines
4.3 KiB
TypeScript

import ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation";
import IdentityProviderRepresentation from "@keycloak/keycloak-admin-client/lib/defs/identityProviderRepresentation";
import { Page, expect, test } from "@playwright/test";
import { randomUUID } from "node:crypto";
import {
createClient,
createIdentityProvider,
createRandomUserWithPassword,
deleteClient,
deleteIdentityProvider,
deleteUser,
findClientByClientId,
inRealm,
} from "../admin-client";
import { SERVER_URL } from "../constants";
import groupsIdPClient from "../realms/groups-idp.json" assert { type: "json" };
const realm = "groups";
test.describe("Account linking", () => {
let groupIdPClientId: string;
let user: string;
// Tests for keycloak account console, section Account linking in Account security
test.beforeAll(async () => {
user = await createRandomUserWithPassword("user-" + randomUUID(), "pwd");
const kcGroupsIdpId = await findClientByClientId("groups-idp");
if (kcGroupsIdpId) {
await deleteClient(kcGroupsIdpId);
}
groupIdPClientId = await createClient(
groupsIdPClient as ClientRepresentation,
);
const idp: IdentityProviderRepresentation = {
alias: "master-idp",
providerId: "oidc",
enabled: true,
config: {
clientId: "groups-idp",
clientSecret: "H0JaTc7VBu3HJR26vrzMxgidfJmgI5Dw",
validateSignature: "false",
tokenUrl: `${SERVER_URL}/realms/master/protocol/openid-connect/token`,
jwksUrl: `${SERVER_URL}/realms/master/protocol/openid-connect/certs`,
issuer: `${SERVER_URL}/realms/master`,
authorizationUrl: `${SERVER_URL}/realms/master/protocol/openid-connect/auth`,
logoutUrl: `${SERVER_URL}/realms/master/protocol/openid-connect/logout`,
userInfoUrl: `${SERVER_URL}/realms/master/protocol/openid-connect/userinfo`,
},
};
await inRealm(realm, () => createIdentityProvider(idp));
});
test.afterAll(async () => {
await deleteUser(user);
});
test.afterAll(async () => {
await deleteClient(groupIdPClientId);
});
test.afterAll(async () => {
await inRealm(realm, () => deleteIdentityProvider("master-idp"));
});
test("Linking", async ({ page }) => {
// If refactoring this, consider introduction of helper functions for individual pages - login, update profile etc.
await page.goto(`/realms/${realm}/account`);
// Click the login via master-idp provider button
await loginWithIdp(page, "master-idp");
// Now the login at the master-idp should be visible
await loginWithUsernamePassword(page, "admin", "admin");
// Now the update-profile page should be visible
await updateProfile(page, "test", "user", "testuser@keycloak.org");
// Now the account console should be visible
await page.getByTestId("accountSecurity").click();
await expect(
page.getByTestId("account-security/linked-accounts"),
).toBeVisible();
await page.getByTestId("account-security/linked-accounts").click();
await expect(
page
.getByTestId("linked-accounts/master-idp")
.getByRole("button", { name: "Unlink account" }),
).toBeVisible();
await page
.getByTestId("linked-accounts/master-idp")
.getByRole("button", { name: "Unlink account" })
.click();
// Expect an error shown that the account cannot be unlinked
await expect(page.getByTestId("last-alert")).toContainText(
"You can''t remove last federated identity as you don''t have a password.",
);
});
});
async function updateProfile(
page: Page,
firstName: string,
lastName: string,
email: string,
) {
await expect(
page.getByRole("heading", { name: "Update Account Information" }),
).toBeVisible();
await page.getByLabel("Email").fill(email);
await page.getByLabel("First name").fill(firstName);
await page.getByLabel("Last name").fill(lastName);
await page.getByRole("button", { name: "Submit" }).click();
}
async function loginWithUsernamePassword(page, username, password) {
await page.getByLabel("Username").fill(username);
await page.getByLabel("Password", { exact: true }).fill(password);
await page.getByRole("button", { name: "Sign In" }).click();
}
async function loginWithIdp(page, idpAlias: string) {
await page.getByRole("link", { name: idpAlias }).click();
}