updated and fixed user test (#1956)
* updated and fixed user test * Update cypress/integration/users_test.spec.ts * fixed the confirm button test id * fixed tests * fix * removed unused refresh Co-authored-by: Jenny <32821331+jenny-s51@users.noreply.github.com>
This commit is contained in:
parent
b9224862de
commit
6a970e6cb7
30 changed files with 289 additions and 287 deletions
|
@ -4,7 +4,10 @@ import ListingPage from "../support/pages/admin_console/ListingPage";
|
|||
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import AdminClient from "../support/util/AdminClient";
|
||||
import { keycloakBefore } from "../support/util/keycloak_hooks";
|
||||
import {
|
||||
keycloakBefore,
|
||||
keycloakBeforeEach,
|
||||
} from "../support/util/keycloak_hooks";
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
|
@ -22,6 +25,8 @@ describe("Clients SAML tests", () => {
|
|||
clientId: samlClientName,
|
||||
publicClient: false,
|
||||
});
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -29,8 +34,7 @@ describe("Clients SAML tests", () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
keycloakBeforeEach();
|
||||
sidebarPage.goToClients();
|
||||
listingPage.searchItem(samlClientName).goToItemDetails(samlClientName);
|
||||
});
|
||||
|
@ -62,6 +66,8 @@ describe("Clients SAML tests", () => {
|
|||
clientId,
|
||||
protocol: "saml",
|
||||
});
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -69,8 +75,7 @@ describe("Clients SAML tests", () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
keycloakBeforeEach();
|
||||
sidebarPage.goToClients();
|
||||
listingPage.searchItem(clientId).goToItemDetails(clientId);
|
||||
cy.findByTestId("keysTab").click();
|
||||
|
@ -87,7 +92,11 @@ describe("Clients SAML tests", () => {
|
|||
});
|
||||
|
||||
it("disable client signature", () => {
|
||||
cy.intercept(
|
||||
"auth/admin/realms/master/clients/*/certificates/saml.signing"
|
||||
).as("load");
|
||||
cy.findByTestId("clientSignature").click({ force: true });
|
||||
cy.waitFor("@load");
|
||||
|
||||
modalUtils
|
||||
.checkModalTitle('Disable "Client signature required"')
|
||||
|
|
|
@ -282,7 +282,7 @@ describe("Clients test", () => {
|
|||
cy.findByTestId("mappersTab").click();
|
||||
cy.findByText("Add predefined mapper").click();
|
||||
cy.get("table input").first().click();
|
||||
cy.findByTestId("modalConfirm").click();
|
||||
cy.findByTestId("confirm").click();
|
||||
masthead.checkNotificationMessage("Mapping successfully created");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -128,7 +128,7 @@ describe("Identity provider test", () => {
|
|||
listingPage.goToItemDetails("facebook");
|
||||
addMapperPage.goToMappersTab();
|
||||
listingPage.deleteItem("facebook attribute importer");
|
||||
cy.findByTestId("modalConfirm").click();
|
||||
cy.findByTestId("confirm").click();
|
||||
});
|
||||
|
||||
it("clean up providers", () => {
|
||||
|
|
|
@ -17,6 +17,7 @@ describe("Partial import test", () => {
|
|||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.waitForPageLoad();
|
||||
|
||||
// doing this from the UI has the added bonus of putting you in the test realm
|
||||
sidebarPage.goToCreateRealm();
|
||||
|
|
|
@ -6,8 +6,10 @@ import ListingPage from "../support/pages/admin_console/ListingPage";
|
|||
import UserDetailsPage from "../support/pages/admin_console/manage/users/UserDetailsPage";
|
||||
import AttributesTab from "../support/pages/admin_console/manage/AttributesTab";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
import { keycloakBefore } from "../support/util/keycloak_hooks";
|
||||
import GroupModal from "../support/pages/admin_console/manage/groups/GroupModal";
|
||||
import {
|
||||
keycloakBefore,
|
||||
keycloakBeforeEach,
|
||||
} from "../support/util/keycloak_hooks";
|
||||
import UserGroupsPage from "../support/pages/admin_console/manage/users/UserGroupsPage";
|
||||
import AdminClient from "../support/util/AdminClient";
|
||||
import CredentialsPage from "../support/pages/admin_console/manage/users/CredentialsPage";
|
||||
|
@ -15,38 +17,7 @@ import CredentialsPage from "../support/pages/admin_console/manage/users/Credent
|
|||
let groupName = "group";
|
||||
let groupsList: string[] = [];
|
||||
|
||||
describe("Group creation", () => {
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
const sidebarPage = new SidebarPage();
|
||||
const groupModal = new GroupModal();
|
||||
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToGroups();
|
||||
});
|
||||
|
||||
function createNewGroup() {
|
||||
groupName += "_" + (Math.random() + 1).toString(36).substring(7);
|
||||
|
||||
sidebarPage.waitForPageLoad();
|
||||
groupModal.open().fillGroupForm(groupName).clickCreate();
|
||||
|
||||
groupsList = [...groupsList, groupName];
|
||||
masthead.checkNotificationMessage("Group created");
|
||||
|
||||
sidebarPage.goToGroups();
|
||||
}
|
||||
|
||||
it("Add groups to be joined", () => {
|
||||
for (let i = 0; i <= 2; i++) {
|
||||
createNewGroup();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Users test", () => {
|
||||
describe("User creation", () => {
|
||||
const loginPage = new LoginPage();
|
||||
const sidebarPage = new SidebarPage();
|
||||
const createUserPage = new CreateUserPage();
|
||||
|
@ -60,217 +31,208 @@ describe("Users test", () => {
|
|||
|
||||
let itemId = "user_crud";
|
||||
let itemIdWithCred = "user_crud_cred";
|
||||
const adminClient = new AdminClient();
|
||||
|
||||
describe("User creation", () => {
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
cy.intercept(
|
||||
"/auth/admin/realms/master/components?type=org.keycloak.storage.UserStorageProvider"
|
||||
).as("brute-force");
|
||||
sidebarPage.goToUsers();
|
||||
before(() => {
|
||||
for (let i = 0; i <= 2; i++) {
|
||||
groupName += "_" + (Math.random() + 1).toString(36).substring(7);
|
||||
adminClient.createGroup(groupName);
|
||||
groupsList = [...groupsList, groupName];
|
||||
}
|
||||
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
keycloakBeforeEach();
|
||||
sidebarPage.goToUsers();
|
||||
});
|
||||
|
||||
after(() => {
|
||||
adminClient.deleteGroups();
|
||||
});
|
||||
|
||||
it("Go to create User page", () => {
|
||||
createUserPage.goToCreateUser();
|
||||
cy.url().should("include", "users/add-user");
|
||||
|
||||
// Verify Cancel button works
|
||||
createUserPage.cancel();
|
||||
cy.url().should("not.include", "/add-user");
|
||||
});
|
||||
|
||||
it("Create user test", () => {
|
||||
itemId += "_" + (Math.random() + 1).toString(36).substring(7);
|
||||
|
||||
// Create
|
||||
createUserPage.goToCreateUser();
|
||||
|
||||
createUserPage.createUser(itemId);
|
||||
|
||||
createUserPage.toggleAddGroupModal();
|
||||
|
||||
const groupsListCopy = groupsList.slice(0, 1);
|
||||
|
||||
groupsListCopy.forEach((element) => {
|
||||
cy.findByTestId(`${element}-check`).click();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await new AdminClient().deleteGroups();
|
||||
});
|
||||
createUserPage.joinGroups();
|
||||
|
||||
it("Go to create User page", () => {
|
||||
createUserPage.goToCreateUser();
|
||||
cy.url().should("include", "users/add-user");
|
||||
createUserPage.save();
|
||||
|
||||
// Verify Cancel button works
|
||||
createUserPage.cancel();
|
||||
cy.url().should("not.include", "/add-user");
|
||||
});
|
||||
masthead.checkNotificationMessage("The user has been created");
|
||||
});
|
||||
|
||||
it("Create user test", () => {
|
||||
itemId += "_" + (Math.random() + 1).toString(36).substring(7);
|
||||
it("Create user with credentials test", () => {
|
||||
itemIdWithCred += "_" + (Math.random() + 1).toString(36).substring(7);
|
||||
|
||||
// Create
|
||||
createUserPage.goToCreateUser();
|
||||
createUserPage.goToCreateUser();
|
||||
|
||||
createUserPage.createUser(itemId);
|
||||
createUserPage.createUser(itemIdWithCred);
|
||||
|
||||
createUserPage.toggleAddGroupModal();
|
||||
userDetailsPage.fillUserData();
|
||||
createUserPage.save();
|
||||
masthead.checkNotificationMessage("The user has been created");
|
||||
sidebarPage.waitForPageLoad();
|
||||
|
||||
const groupsListCopy = groupsList.slice(0, 1);
|
||||
credentialsPage
|
||||
.goToCredentialsTab()
|
||||
.clickEmptyStatePasswordBtn()
|
||||
.fillPasswordForm()
|
||||
.clickConfirmationBtn()
|
||||
.clickSetPasswordBtn();
|
||||
});
|
||||
|
||||
groupsListCopy.forEach((element) => {
|
||||
cy.findByTestId(`${element}-check`).click();
|
||||
it("User details test", () => {
|
||||
sidebarPage.waitForPageLoad();
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
userDetailsPage.fillUserData().save();
|
||||
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
|
||||
sidebarPage.waitForPageLoad();
|
||||
sidebarPage.goToUsers();
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
});
|
||||
|
||||
it("User attributes test", () => {
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
attributesTab
|
||||
.goToAttributesTab()
|
||||
.fillLastRow("key", "value")
|
||||
.saveAttribute();
|
||||
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
});
|
||||
|
||||
it("User attributes with multiple values test", () => {
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
cy.intercept("PUT", `/auth/admin/realms/master/users/*`).as("save-user");
|
||||
|
||||
const attributeKey = "key-multiple";
|
||||
attributesTab
|
||||
.goToAttributesTab()
|
||||
.fillLastRow(attributeKey, "other value")
|
||||
.saveAttribute();
|
||||
|
||||
cy.wait("@save-user").should(({ request, response }) => {
|
||||
expect(response?.statusCode).to.equal(204);
|
||||
|
||||
expect(request?.body.attributes, "response body").deep.equal({
|
||||
key: ["value"],
|
||||
"key-multiple": ["other value"],
|
||||
});
|
||||
|
||||
createUserPage.joinGroups();
|
||||
|
||||
createUserPage.save();
|
||||
|
||||
masthead.checkNotificationMessage("The user has been created");
|
||||
|
||||
sidebarPage.goToUsers();
|
||||
});
|
||||
|
||||
it("Create user with credentials test", () => {
|
||||
itemIdWithCred += "_" + (Math.random() + 1).toString(36).substring(7);
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
});
|
||||
|
||||
createUserPage.goToCreateUser();
|
||||
it("Add user to groups test", () => {
|
||||
// Go to user groups
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
createUserPage.createUser(itemIdWithCred);
|
||||
userGroupsPage.goToGroupsTab();
|
||||
userGroupsPage.toggleAddGroupModal();
|
||||
|
||||
createUserPage.save();
|
||||
const groupsListCopy = groupsList.slice(1, 2);
|
||||
|
||||
masthead.checkNotificationMessage("The user has been created");
|
||||
|
||||
sidebarPage.goToUsers();
|
||||
|
||||
listingPage.goToItemDetails(itemIdWithCred);
|
||||
|
||||
userDetailsPage.fillUserData().save();
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
|
||||
credentialsPage
|
||||
.goToCredentialsTab()
|
||||
.clickEmptyStatePasswordBtn()
|
||||
.fillPasswordForm()
|
||||
.clickConfirmationBtn()
|
||||
.clickSetPasswordBtn();
|
||||
|
||||
sidebarPage.goToUsers();
|
||||
groupsListCopy.forEach((element) => {
|
||||
cy.findByTestId(`${element}-check`).click();
|
||||
});
|
||||
|
||||
it("User details test", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
userGroupsPage.joinGroups();
|
||||
});
|
||||
|
||||
listingPage.goToItemDetails(itemId);
|
||||
it("Leave group test", () => {
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
listingPage.goToItemDetails(itemId);
|
||||
// Go to user groups
|
||||
userGroupsPage.goToGroupsTab();
|
||||
cy.findByTestId(`leave-${groupsList[0]}`).click();
|
||||
cy.findByTestId("confirm").click();
|
||||
});
|
||||
|
||||
userDetailsPage.fillUserData().save();
|
||||
it("Go to user consents test", () => {
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
sidebarPage.waitForPageLoad();
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
sidebarPage.goToUsers();
|
||||
cy.wait("@brute-force");
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
});
|
||||
cy.findByTestId("user-consents-tab").click();
|
||||
cy.findByTestId("empty-state").contains("No consents");
|
||||
});
|
||||
|
||||
it("User attributes test", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
it("Reset credential of User with empty state", () => {
|
||||
listingPage.goToItemDetails(itemId);
|
||||
credentialsPage
|
||||
.goToCredentialsTab()
|
||||
.clickEmptyStateResetBtn()
|
||||
.fillResetCredentialForm();
|
||||
masthead.checkNotificationMessage("Failed to send email to user.");
|
||||
modalUtils.cancelModal();
|
||||
});
|
||||
|
||||
listingPage.goToItemDetails(itemId);
|
||||
it("Reset credential of User with existing credentials", () => {
|
||||
listingPage.goToItemDetails(itemIdWithCred);
|
||||
credentialsPage
|
||||
.goToCredentialsTab()
|
||||
.clickResetBtn()
|
||||
.fillResetCredentialForm();
|
||||
|
||||
attributesTab
|
||||
.goToAttributesTab()
|
||||
.fillLastRow("key", "value")
|
||||
.saveAttribute();
|
||||
masthead.checkNotificationMessage("Failed to send email to user.");
|
||||
modalUtils.cancelModal();
|
||||
});
|
||||
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
});
|
||||
it("Delete user test", () => {
|
||||
// Delete
|
||||
listingPage.deleteItem(itemId);
|
||||
|
||||
it("User attributes with multiple values test", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
modalUtils.checkModalTitle("Delete user?").confirmModal();
|
||||
|
||||
listingPage.goToItemDetails(itemId);
|
||||
masthead.checkNotificationMessage("The user has been deleted");
|
||||
sidebarPage.waitForPageLoad();
|
||||
|
||||
cy.intercept("PUT", `/auth/admin/realms/master/users/*`).as("save-user");
|
||||
listingPage.itemExist(itemId, false);
|
||||
});
|
||||
|
||||
const attributeKey = "key-multiple";
|
||||
attributesTab
|
||||
.goToAttributesTab()
|
||||
.fillLastRow(attributeKey, "other value")
|
||||
.saveAttribute();
|
||||
it("Delete user with credential test", () => {
|
||||
// Delete
|
||||
listingPage.deleteItem(itemIdWithCred);
|
||||
|
||||
cy.wait("@save-user").should(({ request, response }) => {
|
||||
expect(response?.statusCode).to.equal(204);
|
||||
modalUtils.checkModalTitle("Delete user?").confirmModal();
|
||||
|
||||
expect(request?.body.attributes, "response body").deep.equal({
|
||||
key: ["value"],
|
||||
"key-multiple": ["other value"],
|
||||
});
|
||||
});
|
||||
masthead.checkNotificationMessage("The user has been deleted");
|
||||
sidebarPage.waitForPageLoad();
|
||||
|
||||
masthead.checkNotificationMessage("The user has been saved");
|
||||
});
|
||||
|
||||
it("Add user to groups test", () => {
|
||||
cy.wait("@brute-force");
|
||||
// Go to user groups
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
userGroupsPage.goToGroupsTab();
|
||||
userGroupsPage.toggleAddGroupModal();
|
||||
|
||||
const groupsListCopy = groupsList.slice(1, 2);
|
||||
|
||||
groupsListCopy.forEach((element) => {
|
||||
cy.findByTestId(`${element}-check`).click();
|
||||
});
|
||||
|
||||
userGroupsPage.joinGroups();
|
||||
});
|
||||
|
||||
it("Leave group test", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
listingPage.goToItemDetails(itemId);
|
||||
// Go to user groups
|
||||
userGroupsPage.goToGroupsTab();
|
||||
cy.findByTestId(`leave-${groupsList[0]}`).click();
|
||||
cy.findByTestId("modalConfirm").click();
|
||||
});
|
||||
|
||||
it("Go to user consents test", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.searchItem(itemId).itemExist(itemId);
|
||||
|
||||
listingPage.goToItemDetails(itemId);
|
||||
|
||||
cy.findByTestId("user-consents-tab").click();
|
||||
cy.findByTestId("empty-state").contains("No consents");
|
||||
});
|
||||
|
||||
it("Reset credential of User with empty state", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.goToItemDetails(itemId);
|
||||
credentialsPage
|
||||
.goToCredentialsTab()
|
||||
.clickEmptyStateResetBtn()
|
||||
.fillResetCredentialForm();
|
||||
masthead.checkNotificationMessage("Failed to send email to user.");
|
||||
});
|
||||
|
||||
it("Reset credential of User with existing credentials", () => {
|
||||
cy.wait("@brute-force");
|
||||
listingPage.goToItemDetails(itemIdWithCred);
|
||||
credentialsPage
|
||||
.goToCredentialsTab()
|
||||
.clickResetBtn()
|
||||
.fillResetCredentialForm();
|
||||
|
||||
masthead.checkNotificationMessage("Failed to send email to user.");
|
||||
});
|
||||
|
||||
it("Delete user test", () => {
|
||||
// Delete
|
||||
listingPage.deleteItem(itemId);
|
||||
|
||||
modalUtils.checkModalTitle("Delete user?").confirmModal();
|
||||
|
||||
masthead.checkNotificationMessage("The user has been deleted");
|
||||
|
||||
listingPage.itemExist(itemId, false);
|
||||
});
|
||||
|
||||
it("Delete user with credential test", () => {
|
||||
// Delete
|
||||
listingPage.deleteItem(itemIdWithCred);
|
||||
|
||||
modalUtils.checkModalTitle("Delete user?").confirmModal();
|
||||
|
||||
masthead.checkNotificationMessage("The user has been deleted");
|
||||
|
||||
listingPage.itemExist(itemIdWithCred, false);
|
||||
});
|
||||
listingPage.itemExist(itemIdWithCred, false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -24,10 +24,9 @@ export default class SidebarPage {
|
|||
|
||||
goToRealm(realmName: string) {
|
||||
cy.findByTestId(this.realmsList).scrollIntoView().click();
|
||||
cy.findByTestId(this.realmsList)
|
||||
.get("ul")
|
||||
.contains(capitalize(realmName))
|
||||
.click();
|
||||
cy.findByTestId(this.realmsList).within(() => {
|
||||
cy.get("ul").contains(capitalize(realmName)).click();
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ export default class RoleMappingTab {
|
|||
private hideInheritedRolesBtn = "#hideInheritedRoles";
|
||||
private assignedRolesTable = "assigned-roles";
|
||||
private namesColumn = 'td[data-label="Name"]:visible';
|
||||
private confirmModalBtn = "modalConfirm";
|
||||
|
||||
goToServiceAccountTab() {
|
||||
cy.findByTestId(this.tab).click();
|
||||
|
|
|
@ -85,7 +85,7 @@ export default class RealmSettingsPage {
|
|||
keyInput = "key-input";
|
||||
valueInput = "value-input";
|
||||
deleteAction = "delete-action";
|
||||
modalConfirm = "modalConfirm";
|
||||
modalConfirm = "confirm";
|
||||
ssoSessionIdleInput = "sso-session-idle-input";
|
||||
ssoSessionMaxInput = "sso-session-max-input";
|
||||
ssoSessionIdleRememberMeInput = "sso-session-idle-remember-me-input";
|
||||
|
@ -625,7 +625,7 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"This action will permanently delete the policy Test. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.get(this.deleteDialogCancelBtn).contains("Cancel").click();
|
||||
cy.get("table").should("be.visible").contains("td", "Test");
|
||||
}
|
||||
|
@ -633,7 +633,8 @@ export default class RealmSettingsPage {
|
|||
shouldDeleteClientProfileDialog() {
|
||||
this.listingPage.searchItem("Test", false);
|
||||
this.listingPage.clickRowDetails("Test").clickDetailMenu("Delete");
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).click();
|
||||
cy.get(this.alertMessage).should("be.visible", "Client profile deleted");
|
||||
cy.get("table").should("not.have.text", "Test");
|
||||
}
|
||||
|
@ -755,7 +756,7 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"The action will permanently delete secure-ciba-signed-authn-req. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.get(this.deleteDialogCancelBtn).contains("Cancel").click();
|
||||
cy.get('ul[class*="pf-c-data-list"]').should(
|
||||
"have.text",
|
||||
|
@ -802,7 +803,8 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"The action will permanently delete secure-ciba-signed-authn-req. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).click();
|
||||
cy.get('h6[class*="kc-emptyExecutors"]').should(
|
||||
"have.text",
|
||||
"No executors configured"
|
||||
|
@ -813,12 +815,12 @@ export default class RealmSettingsPage {
|
|||
cy.get('[data-label="Name"]')
|
||||
.contains("Edit")
|
||||
.parentsUntil("tbody")
|
||||
.get(this.moreDrpDwn)
|
||||
.last()
|
||||
.click()
|
||||
.get(this.moreDrpDwnItems)
|
||||
.click();
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
.within(() => {
|
||||
cy.get(this.moreDrpDwn).click();
|
||||
});
|
||||
cy.get(this.moreDrpDwnItems).click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).click();
|
||||
cy.get(this.alertMessage).should("be.visible", "Client profile deleted");
|
||||
cy.get("table").should("not.have.text", "Edit");
|
||||
}
|
||||
|
@ -843,7 +845,8 @@ export default class RealmSettingsPage {
|
|||
);
|
||||
cy.get(this.createClientDrpDwn).contains("Action").click();
|
||||
cy.findByTestId("deleteClientProfileDropdown").click();
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).click();
|
||||
cy.get(this.alertMessage).should("be.visible", "Client profile deleted");
|
||||
cy.get("table").should("not.have.text", "Test Again Description");
|
||||
}
|
||||
|
@ -956,7 +959,7 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"This action will permanently delete the profile Test. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.get(this.deleteDialogCancelBtn).contains("Cancel").click();
|
||||
cy.get("table").should("be.visible").contains("td", "Test");
|
||||
}
|
||||
|
@ -1008,11 +1011,11 @@ export default class RealmSettingsPage {
|
|||
|
||||
addClientScopes() {
|
||||
cy.findByTestId(this.selectScopeButton).click();
|
||||
cy.get(".pf-c-table__check > label > input[name=checkrow0]").click();
|
||||
cy.get(".pf-c-table__check > label > input[name=checkrow1]").click();
|
||||
cy.get(".pf-c-table__check > label > input[name=checkrow2]").click();
|
||||
cy.get(".pf-c-table__check > input[name=checkrow0]").click();
|
||||
cy.get(".pf-c-table__check > input[name=checkrow1]").click();
|
||||
cy.get(".pf-c-table__check > input[name=checkrow2]").click();
|
||||
|
||||
cy.findByTestId("modalConfirm").contains("Add").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Add").click();
|
||||
}
|
||||
|
||||
shouldAddClientScopesCondition() {
|
||||
|
@ -1079,8 +1082,9 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"This action will permanently delete client-roles. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete");
|
||||
cy.get(this.deleteDialogCancelBtn).contains("Cancel").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.get(this.deleteDialogCancelBtn).contains("Cancel");
|
||||
cy.get(this.deleteDialogCancelBtn).click();
|
||||
cy.get('ul[class*="pf-c-data-list"]').contains("client-roles");
|
||||
}
|
||||
|
||||
|
@ -1091,7 +1095,8 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"This action will permanently delete client-roles. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).click();
|
||||
cy.get('ul[class*="pf-c-data-list"]').contains("client-scopes");
|
||||
}
|
||||
|
||||
|
@ -1102,7 +1107,8 @@ export default class RealmSettingsPage {
|
|||
cy.get(this.deleteDialogBodyText).contains(
|
||||
"This action will permanently delete client-scopes. This cannot be undone."
|
||||
);
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete");
|
||||
cy.findByTestId(this.modalConfirm).click();
|
||||
cy.get('h6[class*="kc-emptyConditions"]').should(
|
||||
"have.text",
|
||||
"No conditions configured"
|
||||
|
@ -1112,7 +1118,7 @@ export default class RealmSettingsPage {
|
|||
shouldDeleteClientPolicyDialog() {
|
||||
this.listingPage.searchItem("Test", false);
|
||||
this.listingPage.clickRowDetails("Test").clickDetailMenu("Delete");
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete").click();
|
||||
cy.get(this.alertMessage).should("be.visible", "Client profile deleted");
|
||||
cy.get("table").should("not.have.text", "Test");
|
||||
}
|
||||
|
@ -1135,7 +1141,7 @@ export default class RealmSettingsPage {
|
|||
|
||||
cy.findByTestId(this.clientPolicyDrpDwn).contains("Action").click();
|
||||
cy.findByTestId("deleteClientPolicyDropdown").click();
|
||||
cy.findByTestId("modalConfirm").contains("Delete").click();
|
||||
cy.findByTestId(this.modalConfirm).contains("Delete").click();
|
||||
cy.get(this.alertMessage).should("be.visible", "Client profile deleted");
|
||||
cy.findByTestId(this.createPolicyEmptyStateBtn).should("exist");
|
||||
}
|
||||
|
|
|
@ -52,6 +52,11 @@ export default class AdminClient {
|
|||
await this.client.clients.del({ id: client.id! });
|
||||
}
|
||||
|
||||
async createGroup(groupName: string) {
|
||||
await this.login();
|
||||
return await this.client.groups.create({ name: groupName });
|
||||
}
|
||||
|
||||
async createSubGroups(groups: string[]) {
|
||||
await this.login();
|
||||
let parentGroup = undefined;
|
||||
|
|
|
@ -2,18 +2,18 @@ export default class ModalUtils {
|
|||
private modalTitle = ".pf-c-modal-box .pf-c-modal-box__title-text";
|
||||
private modalMessage = ".pf-c-modal-box .pf-c-modal-box__body";
|
||||
|
||||
private confirmModalBtn = "#modal-confirm";
|
||||
private cancelModalBtn = "#modal-cancel";
|
||||
private confirmModalBtn = "confirm";
|
||||
private cancelModalBtn = "cancel";
|
||||
private closeModalBtn = ".pf-c-modal-box .pf-m-plain";
|
||||
|
||||
confirmModal(force = false) {
|
||||
cy.get(this.confirmModalBtn).click({ force });
|
||||
cy.findByTestId(this.confirmModalBtn).click({ force });
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
cancelModal() {
|
||||
cy.get(this.cancelModalBtn).click();
|
||||
cy.findByTestId(this.cancelModalBtn).click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ describe("MapperDialog", () => {
|
|||
|
||||
fireEvent.click(screen.getByText("Show"));
|
||||
|
||||
expect(screen.getByTestId("modalConfirm")).toHaveClass("pf-m-disabled");
|
||||
expect(screen.getByTestId("confirm")).toHaveClass("pf-m-disabled");
|
||||
});
|
||||
|
||||
it("returns array with selected build in protocol mapping", () => {
|
||||
|
@ -55,7 +55,7 @@ describe("MapperDialog", () => {
|
|||
fireEvent.click(screen.getByText("Show"));
|
||||
fireEvent.click(screen.getByLabelText("Select row 0"));
|
||||
fireEvent.click(screen.getByLabelText("Select row 1"));
|
||||
fireEvent.click(screen.getByTestId("modalConfirm"));
|
||||
fireEvent.click(screen.getByTestId("confirm"));
|
||||
|
||||
expect(onConfirm).toBeCalledWith([
|
||||
serverInfo.builtinProtocolMappers[protocol][0],
|
||||
|
|
|
@ -107,7 +107,7 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
|
|||
? [
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
data-testid="modalConfirm"
|
||||
data-testid="confirm"
|
||||
key="confirm"
|
||||
isDisabled={rows.length === 0 || selectedRows.length === 0}
|
||||
onClick={() => {
|
||||
|
@ -119,6 +119,7 @@ export const AddMapperDialog = (props: AddMapperDialogProps) => {
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -61,6 +61,7 @@ export const ImportKeyDialog = ({
|
|||
actions={[
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
data-testid="confirm"
|
||||
key="confirm"
|
||||
onClick={() => {
|
||||
handleSubmit((importFile) => {
|
||||
|
@ -73,6 +74,7 @@ export const ImportKeyDialog = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -147,7 +147,7 @@ export const AddScopeDialog = ({
|
|||
? [
|
||||
<Button
|
||||
id="modal-add"
|
||||
data-testid="modalConfirm"
|
||||
data-testid="confirm"
|
||||
key="add"
|
||||
variant={ButtonVariant.primary}
|
||||
onClick={() => {
|
||||
|
@ -160,6 +160,7 @@ export const AddScopeDialog = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -30,7 +30,7 @@ describe("ConfirmDialog", () => {
|
|||
render(<Test />);
|
||||
fireEvent.click(screen.getByTestId("show"));
|
||||
|
||||
const confirmButton = screen.getByTestId("modalConfirm");
|
||||
const confirmButton = screen.getByTestId("confirm");
|
||||
expect(confirmButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(confirmButton);
|
||||
|
|
|
@ -71,7 +71,7 @@ export const ConfirmDialogModal = ({
|
|||
actions={[
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
data-testid="modalConfirm"
|
||||
data-testid="confirm"
|
||||
key="confirm"
|
||||
isDisabled={confirmButtonDisabled}
|
||||
variant={continueButtonVariant || ButtonVariant.primary}
|
||||
|
@ -85,6 +85,7 @@ export const ConfirmDialogModal = ({
|
|||
!noCancelButton && (
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -78,6 +78,7 @@ export const GroupsModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -67,6 +67,7 @@ export const ManageOderDialog = ({
|
|||
actions={[
|
||||
<Button
|
||||
id="modal-confirm"
|
||||
data-testid="confirm"
|
||||
key="confirm"
|
||||
onClick={() => {
|
||||
order.map(async (alias, index) => {
|
||||
|
@ -87,6 +88,7 @@ export const ManageOderDialog = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={onClose}
|
||||
|
|
|
@ -50,6 +50,7 @@ export const AddMessageBundleModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -62,6 +62,7 @@ export const AddUserEmailModal = ({ callback }: AddUserEmailModalProps) => {
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={cancel}
|
||||
|
|
|
@ -84,6 +84,7 @@ JavaKeystoreModalProps) => {
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -92,9 +92,6 @@ export default function NewClientPolicyForm() {
|
|||
const form = useForm<ClientPolicyRepresentation>({ mode: "onChange" });
|
||||
const { handleSubmit } = form;
|
||||
|
||||
const [key, setKey] = useState(0);
|
||||
const refresh = () => setKey(new Date().getTime());
|
||||
|
||||
const formValues = form.getValues();
|
||||
|
||||
type ClientPoliciesHeaderProps = {
|
||||
|
@ -102,7 +99,6 @@ export default function NewClientPolicyForm() {
|
|||
value: boolean;
|
||||
save: () => void;
|
||||
realmName: string;
|
||||
refresh: () => void;
|
||||
};
|
||||
|
||||
const ClientPoliciesHeader = ({
|
||||
|
@ -192,7 +188,7 @@ export default function NewClientPolicyForm() {
|
|||
setShowAddConditionsAndProfilesForm(true);
|
||||
}
|
||||
},
|
||||
[key]
|
||||
[]
|
||||
);
|
||||
|
||||
const setupForm = (policy: ClientPolicyRepresentation) => {
|
||||
|
@ -252,7 +248,6 @@ export default function NewClientPolicyForm() {
|
|||
`/${realm}/realm-settings/clientPolicies/${createdForm.name}/edit-policy`
|
||||
);
|
||||
setShowAddConditionsAndProfilesForm(true);
|
||||
refresh();
|
||||
} catch (error) {
|
||||
addError("realm-settings:createClientPolicyError", error);
|
||||
}
|
||||
|
@ -306,7 +301,6 @@ export default function NewClientPolicyForm() {
|
|||
history.push(
|
||||
`/${realm}/realm-settings/clientPolicies/${formValues.name}/edit-policy`
|
||||
);
|
||||
refresh();
|
||||
} catch (error) {
|
||||
addError(t("deleteConditionError"), error);
|
||||
}
|
||||
|
@ -383,10 +377,6 @@ export default function NewClientPolicyForm() {
|
|||
form.setValue("description", currentPolicy?.description);
|
||||
};
|
||||
|
||||
const refreshHeader = () => {
|
||||
setKey(new Date().getTime());
|
||||
};
|
||||
|
||||
const toggleModal = () => {
|
||||
setProfilesModalOpen(!profilesModalOpen);
|
||||
};
|
||||
|
@ -450,7 +440,6 @@ export default function NewClientPolicyForm() {
|
|||
value={value}
|
||||
onChange={onChange}
|
||||
realmName={realm}
|
||||
refresh={refreshHeader}
|
||||
save={save}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -83,6 +83,7 @@ export const RSAGeneratedModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -102,6 +102,7 @@ export const RSAModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -55,6 +55,7 @@ export const LogoutAllSessionsModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -169,6 +169,7 @@ export const RevocationModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -494,7 +494,7 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
{t("save")}
|
||||
</Button>,
|
||||
<Button
|
||||
data-testid="cancelBtn"
|
||||
data-testid="cancel"
|
||||
key={`cancelBtn-${user.id}`}
|
||||
variant="link"
|
||||
form="userCredentials-form"
|
||||
|
@ -606,7 +606,7 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
{isResetPassword ? t("resetPassword") : t("savePassword")}
|
||||
</Button>,
|
||||
<Button
|
||||
data-testid="cancelSetPasswordBtn"
|
||||
data-testid="cancel"
|
||||
key={`cancelConfirmBtn-${user.id}`}
|
||||
variant="link"
|
||||
form="userCredentials-form"
|
||||
|
@ -653,7 +653,7 @@ export const UserCredentials = ({ user }: UserCredentialsProps) => {
|
|||
{t("credentialResetConfirm")}
|
||||
</Button>,
|
||||
<Button
|
||||
data-testid="cancelBtn"
|
||||
data-testid="cancel"
|
||||
key={`cancelBtn-${user.id}`}
|
||||
variant="link"
|
||||
form="userCredentialsReset-form"
|
||||
|
|
|
@ -77,6 +77,7 @@ export const UserIdpModal = ({
|
|||
</Button>,
|
||||
<Button
|
||||
id="modal-cancel"
|
||||
data-testid="cancel"
|
||||
key="cancel"
|
||||
variant={ButtonVariant.link}
|
||||
onClick={() => {
|
||||
|
|
|
@ -39,9 +39,10 @@ import { useRealm } from "../context/realm-context/RealmContext";
|
|||
import { emptyFormatter } from "../util";
|
||||
import { toUser } from "./routes/User";
|
||||
import { toAddUser } from "./routes/AddUser";
|
||||
import helpUrls from "../help-urls";
|
||||
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
||||
import "./user-section.css";
|
||||
import helpUrls from "../help-urls";
|
||||
|
||||
type BruteUser = UserRepresentation & {
|
||||
brute?: Record<string, object>;
|
||||
|
@ -53,7 +54,7 @@ export default function UsersSection() {
|
|||
const { addAlert, addError } = useAlerts();
|
||||
const { realm: realmName } = useRealm();
|
||||
const history = useHistory();
|
||||
const [listUsers, setListUsers] = useState(false);
|
||||
const [userStorage, setUserStorage] = useState<ComponentRepresentation[]>();
|
||||
const [searchUser, setSearchUser] = useState<string>();
|
||||
const [realm, setRealm] = useState<RealmRepresentation | undefined>();
|
||||
const [kebabOpen, setKebabOpen] = useState(false);
|
||||
|
@ -63,27 +64,26 @@ export default function UsersSection() {
|
|||
const refresh = () => setKey(`${new Date().getTime()}`);
|
||||
|
||||
useFetch(
|
||||
() => {
|
||||
async () => {
|
||||
const testParams = {
|
||||
type: "org.keycloak.storage.UserStorageProvider",
|
||||
};
|
||||
|
||||
return Promise.all([
|
||||
adminClient.components.find(testParams),
|
||||
adminClient.realms.findOne({ realm: realmName }),
|
||||
]).catch(
|
||||
() =>
|
||||
[[], undefined] as [
|
||||
ComponentRepresentation[],
|
||||
RealmRepresentation | undefined
|
||||
]
|
||||
);
|
||||
try {
|
||||
return await Promise.all([
|
||||
adminClient.components.find(testParams),
|
||||
adminClient.realms.findOne({ realm: realmName }),
|
||||
]);
|
||||
} catch {
|
||||
return [[], undefined] as [
|
||||
ComponentRepresentation[],
|
||||
RealmRepresentation | undefined
|
||||
];
|
||||
}
|
||||
},
|
||||
([storageProviders, realm]) => {
|
||||
//should *only* list users when no user federation is configured
|
||||
setListUsers(!(storageProviders.length > 0));
|
||||
setUserStorage(storageProviders);
|
||||
setRealm(realm);
|
||||
refresh();
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
@ -204,6 +204,13 @@ export default function UsersSection() {
|
|||
|
||||
const goToCreate = () => history.push(toAddUser({ realm: realmName }));
|
||||
|
||||
if (!userStorage) {
|
||||
return <KeycloakSpinner />;
|
||||
}
|
||||
|
||||
//should *only* list users when no user federation is configured
|
||||
const listUsers = !(userStorage.length > 0);
|
||||
|
||||
const toolbar = (
|
||||
<>
|
||||
<ToolbarItem>
|
||||
|
@ -257,6 +264,10 @@ export default function UsersSection() {
|
|||
</>
|
||||
);
|
||||
|
||||
if (!realm) {
|
||||
return <KeycloakSpinner />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<DeleteConfirm />
|
||||
|
|
|
@ -29,6 +29,7 @@ import { UserRoleMapping } from "./UserRoleMapping";
|
|||
import { UserAttributes } from "./UserAttributes";
|
||||
import { UserCredentials } from "./UserCredentials";
|
||||
import { useAccess } from "../context/access/Access";
|
||||
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||
|
||||
const UsersTabs = () => {
|
||||
const { t } = useTranslation("users");
|
||||
|
@ -142,6 +143,10 @@ const UsersTabs = () => {
|
|||
},
|
||||
});
|
||||
|
||||
if (id && !user) {
|
||||
return <KeycloakSpinner />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ImpersonateConfirm />
|
||||
|
|
Loading…
Reference in a new issue