Add user profile tests for Checks that attribute with select annotation (#26899)

Closes #26898

Signed-off-by: Daniel Fesenmeyer <daniel.fesenmeyer@bosch.com>
This commit is contained in:
Daniel Fesenmeyer 2024-02-09 17:34:55 +01:00 committed by GitHub
parent 5f0ee7b0f7
commit 20e535a3f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 582 additions and 299 deletions

View file

@ -9,6 +9,7 @@ import { keycloakBefore } from "../support/util/keycloak_hooks";
import ModalUtils from "../support/util/ModalUtils";
import RealmSettingsPage from "../support/pages/admin-ui/manage/realm_settings/RealmSettingsPage";
import CreateUserPage from "../support/pages/admin-ui/manage/users/CreateUserPage";
import { UserProfileConfig } from "@keycloak/keycloak-admin-client/lib/defs/userProfileMetadata";
const loginPage = new LoginPage();
const sidebarPage = new SidebarPage();
@ -24,45 +25,58 @@ const getUserProfileTab = () => userProfileTab.goToTab();
const getAttributesTab = () => userProfileTab.goToAttributesTab();
const getAttributesGroupTab = () => userProfileTab.goToAttributesGroupTab();
const getJsonEditorTab = () => userProfileTab.goToJsonEditorTab();
const clickCreateAttributeButton = () =>
userProfileTab.createAttributeButtonClick();
const usernameAttributeName = "username";
const emailAttributeName = "email";
let defaultUserProfile: UserProfileConfig;
describe("User profile tabs", () => {
const realmName = "Realm_" + uuid();
const attributeName = "Test";
const attributeDisplayName = "Test display name";
before(() => adminClient.createRealm(realmName));
after(() => adminClient.deleteRealm(realmName));
before(() => {
cy.wrap(null).then(async () => {
await adminClient.createRealm(realmName);
defaultUserProfile = await adminClient.getUserProfile(realmName);
});
});
after(() =>
cy.wrap(null).then(async () => await adminClient.deleteRealm(realmName)),
);
beforeEach(() => {
loginPage.logIn();
keycloakBefore();
sidebarPage.goToRealm(realmName);
sidebarPage.goToRealmSettings();
cy.wrap(null).then(async () => {
await adminClient.updateUserProfile(realmName, defaultUserProfile);
await adminClient.updateRealm(realmName, {
registrationEmailAsUsername: false,
editUsernameAllowed: false,
});
});
afterEach(() => {
sidebarPage.goToRealm(realmName);
sidebarPage.goToRealmSettings();
sidebarPage.waitForPageLoad();
realmSettingsPage.goToLoginTab();
cy.wait(1000);
cy.findByTestId("email-as-username-switch").uncheck({ force: true });
cy.findByTestId("edit-username-switch").uncheck({ force: true });
});
describe("Attributes sub tab tests", () => {
it("Goes to create attribute page", () => {
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab.clickOnCreateAttributeButton();
});
it("Completes new attribute form and performs cancel", () => {
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttribute(attributeName, "Test display name")
.clickOnCreateAttributeButton()
.setAttributeNames(attributeName, attributeDisplayName)
.cancelAttributeCreation()
.checkElementNotInList(attributeName);
});
@ -70,33 +84,35 @@ describe("User profile tabs", () => {
it("Completes new attribute form and performs submit", () => {
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttribute(attributeName, "Display name")
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
);
.clickOnCreateAttributeButton()
.setAttributeNames(attributeName, attributeDisplayName)
.saveAttributeCreation()
.assertNotificationSaved();
});
it("Modifies existing attribute and performs save", () => {
getUserProfileTab();
getAttributesTab();
createAttributeDefinition(attributeName);
userProfileTab
.selectElementInList(attributeName)
.editAttribute("Edited display name")
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
);
.saveAttributeCreation()
.assertNotificationSaved();
});
it("Adds and removes validator to/from existing attribute and performs save", () => {
getUserProfileTab();
getAttributesTab();
userProfileTab.selectElementInList(attributeName).cancelAddingValidator();
userProfileTab.addValidator();
cy.get('tbody [data-label="Validator name"]').contains("email");
createAttributeDefinition(attributeName);
userProfileTab
.selectElementInList(attributeName)
.cancelAddingValidator(emailAttributeName);
userProfileTab.addValidator(emailAttributeName);
cy.get('tbody [data-label="Validator name"]').contains(
emailAttributeName,
);
userProfileTab.cancelRemovingValidator();
userProfileTab.removeValidator();
@ -106,15 +122,16 @@ describe("User profile tabs", () => {
describe("Attribute groups sub tab tests", () => {
it("Deletes an attributes group", () => {
const group = "Test";
cy.wrap(null).then(() =>
adminClient.patchUserProfile(realmName, {
groups: [{ name: "Test" }],
groups: [{ name: group }],
}),
);
getUserProfileTab();
getAttributesGroupTab();
listingPage.deleteItem("Test");
listingPage.deleteItem(group);
modalUtils.confirmModal();
listingPage.checkEmptyList();
});
@ -126,9 +143,9 @@ describe("User profile tabs", () => {
{
"attributes": [
{
"name": "email"{downArrow},
"name": "${emailAttributeName}"{downArrow},
{
"name": "username",
"name": "${usernameAttributeName}",
"validations": {
"length": {
"min": 3,
@ -146,274 +163,281 @@ describe("User profile tabs", () => {
});
});
describe("Check attribute presence when creating a user based on email as username and edit username configs enabled/disabled", () => {
describe("Check attributes are displayed and editable on user create/edit", () => {
it("Checks that not required attribute is not present when user is created with email as username and edit username set to disabled", () => {
const attrName = "newAttribute1";
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttributeNotRequiredWithoutPermissions(
"newAttribute1",
"newAttribute1",
)
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer.setNoAttributePermissions(),
);
sidebarPage.goToRealmSettings();
realmSettingsPage.goToLoginTab();
cy.wait(1000);
cy.findByTestId("email-as-username-switch").should("have.value", "off");
cy.findByTestId("edit-username-switch").should("have.value", "off");
realmSettingsPage
.assertSwitch(realmSettingsPage.emailAsUsernameSwitch, false)
.assertSwitch(realmSettingsPage.editUsernameSwitch, false);
// Create user
sidebarPage.goToUsers();
cy.wait(1000);
createUserPage.goToCreateUser();
cy.findByTestId("username").type("testuser7");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage("The user has been created");
cy.get(".pf-c-form__label-text")
.contains("newAttribute1")
.should("not.exist");
createUserPage
.goToCreateUser()
.assertAttributeFieldExists(attrName, false)
.setUsername("testuser7")
.create()
.assertNotificationCreated()
.assertAttributeFieldExists(attrName, false);
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
listingPage.deleteItem("newAttribute1");
listingPage.deleteItem(attrName);
modalUtils.confirmModal();
masthead.checkNotificationMessage("Attribute deleted");
});
it("Checks that not required attribute is not present when user is created/edited with email as username enabled", () => {
const attrName = "newAttribute2";
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttributeNotRequiredWithoutPermissions(
"newAttribute2",
"newAttribute2",
)
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer.setNoAttributePermissions(),
);
sidebarPage.goToRealmSettings();
realmSettingsPage.goToLoginTab();
cy.wait(1000);
cy.findByTestId("email-as-username-switch").check({ force: true });
cy.findByTestId("email-as-username-switch").should("have.value", "on");
cy.findByTestId("edit-username-switch").should("have.value", "off");
realmSettingsPage
.setSwitch(realmSettingsPage.emailAsUsernameSwitch, true)
.assertSwitch(realmSettingsPage.emailAsUsernameSwitch, true)
.assertSwitch(realmSettingsPage.editUsernameSwitch, false);
// Create user
sidebarPage.goToUsers();
createUserPage.goToCreateUser();
cy.findByTestId("email").type("testuser8@gmail.com");
cy.get(".pf-c-form__label-text")
.contains("newAttribute2")
.should("not.exist");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage("The user has been created");
createUserPage
.goToCreateUser()
.setAttributeValue(emailAttributeName, "testuser8@gmail.com")
.assertAttributeFieldExists(attrName, false)
.create()
.assertNotificationCreated();
// Edit user
cy.get(".pf-c-form__label-text")
.contains("newAttribute2")
.should("not.exist");
cy.findByTestId("email").clear();
cy.findByTestId("email").type("testuser9@gmail.com");
cy.findByTestId("save-user").click();
masthead.checkNotificationMessage("The user has been saved");
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
listingPage.deleteItem("newAttribute2");
modalUtils.confirmModal();
masthead.checkNotificationMessage("Attribute deleted");
createUserPage
.assertAttributeFieldExists(attrName, false)
.setAttributeValue(emailAttributeName, "testuser9@gmail.com")
.update()
.assertNotificationUpdated();
});
it("Checks that not required attribute with permissions to view/edit is present when user is created", () => {
const attrName = "newAttribute3";
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttributeNotRequiredWithPermissions(
"newAttribute3",
"newAttribute3",
)
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer.setAllAttributePermissions(),
);
sidebarPage.goToRealmSettings();
realmSettingsPage.goToLoginTab();
cy.wait(1000);
cy.findByTestId("email-as-username-switch").should("have.value", "off");
cy.findByTestId("edit-username-switch").should("have.value", "off");
realmSettingsPage
.assertSwitch(realmSettingsPage.emailAsUsernameSwitch, false)
.assertSwitch(realmSettingsPage.editUsernameSwitch, false);
// Create user
sidebarPage.goToUsers();
createUserPage.goToCreateUser();
cy.findByTestId("username").type("testuser10");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage("The user has been created");
cy.get(".pf-c-form__label-text")
.contains("newAttribute3")
.should("exist");
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
listingPage.deleteItem("newAttribute3");
modalUtils.confirmModal();
masthead.checkNotificationMessage("Attribute deleted");
createUserPage
.goToCreateUser()
.assertAttributeFieldExists(attrName, true)
.setUsername("testuser10")
.create()
.assertNotificationCreated()
.assertAttributeFieldExists(attrName, true);
});
//TODO this test doesn't seem to pass on CI
it.skip("Checks that required attribute with permissions to view/edit is present and required when user is created", () => {
it("Checks that required attribute with permissions to view/edit is present and required when user is created", () => {
const attrName = "newAttribute4";
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttributeRequiredWithPermissions(
"newAttribute4",
"newAttribute4",
)
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer.setAllAttributePermissions().setAttributeRequired(),
);
// Create user
sidebarPage.goToUsers();
createUserPage.goToCreateUser();
cy.findByTestId("username").type("testuser11");
cy.get(".pf-c-form__label-text")
.contains("newAttribute4")
.should("exist");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage(
"Could not create user: Please specify attribute newAttribute4.",
);
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
listingPage.deleteItem("newAttribute4");
modalUtils.confirmModal();
masthead.checkNotificationMessage("Attribute deleted");
createUserPage
.goToCreateUser()
.assertAttributeLabel(attrName, attrName)
.setUsername("testuser11")
.create()
.assertValidationErrorRequired(attrName);
createUserPage
.setAttributeValue(attrName, "MyAttribute")
.create()
.assertNotificationCreated();
});
it("Checks that required attribute with permissions to view/edit is accepted when user is created", () => {
const attrName = "newAttribute5";
getUserProfileTab();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttributeRequiredWithPermissions(
"newAttribute5",
"newAttribute5",
)
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer.setAllAttributePermissions().setAttributeRequired(),
);
// Create user
sidebarPage.goToUsers();
createUserPage.goToCreateUser();
cy.findByTestId("username").type("testuser12");
cy.get(".pf-c-form__label-text")
.contains("newAttribute5")
.should("exist");
cy.findByTestId("newAttribute5").type("MyAttribute");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage("The user has been created");
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
listingPage.deleteItem("newAttribute5");
modalUtils.confirmModal();
masthead.checkNotificationMessage("Attribute deleted");
createUserPage
.goToCreateUser()
.assertAttributeLabel(attrName, attrName)
.setUsername("testuser12")
.setAttributeValue(attrName, "MyAttribute")
.create()
.assertNotificationCreated();
});
it("Checks that attribute group is visible when user with existing attribute is created", () => {
const group = "personalInfo";
getUserProfileTab();
getAttributesGroupTab();
cy.findAllByTestId("no-attributes-groups-empty-action").click();
userProfileTab.createAttributeGroup("personalInfo", "personalInfo");
userProfileTab.saveAttributesGroupCreation();
getAttributesGroupTab()
.clickOnCreatesAttributesGroupButton()
.createAttributeGroup(group, group)
.saveAttributesGroupCreation();
getAttributesTab();
userProfileTab.selectElementInList("username");
cy.get("#kc-attributeGroup").click();
cy.get("button.pf-c-select__menu-item").contains("personalInfo").click();
userProfileTab.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
);
userProfileTab
.selectElementInList(usernameAttributeName)
.setAttributeGroup(group)
.saveAttributeCreation()
.assertNotificationSaved();
// Create user
sidebarPage.goToUsers();
createUserPage.goToCreateUser();
cy.findByTestId("username").type("testuser14");
cy.get("h1#personalinfo").should("have.text", "personalInfo");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage("The user has been created");
createUserPage
.goToCreateUser()
.assertGroupDisplayName(group, group)
.setUsername("testuser14")
.create()
.assertNotificationCreated();
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
userProfileTab.selectElementInList("username");
cy.get("#kc-attributeGroup").click();
cy.get("button.pf-c-select__menu-item").contains("None").click();
userProfileTab.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
userProfileTab
.selectElementInList(usernameAttributeName)
.resetAttributeGroup()
.saveAttributeCreation()
.assertNotificationSaved();
});
it("Checks that attribute group is visible when user with a new attribute is created", () => {
const group = "contact";
const attrName = "address";
getUserProfileTab();
getAttributesGroupTab()
.clickOnCreatesAttributesGroupButton()
.createAttributeGroup(group, group)
.saveAttributesGroupCreation();
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer.setAllAttributePermissions(),
);
getAttributesGroupTab();
listingPage.deleteItem("personalInfo");
modalUtils.confirmModal();
listingPage.checkEmptyList();
});
it("Checks that attribute group is visible when user with a new attribute is created", () => {
getUserProfileTab();
getAttributesGroupTab();
cy.findAllByTestId("no-attributes-groups-empty-action").click();
userProfileTab.createAttributeGroup("contact", "contact");
userProfileTab.saveAttributesGroupCreation();
getAttributesTab();
clickCreateAttributeButton();
userProfileTab
.createAttributeNotRequiredWithPermissions("address", "address")
.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
);
userProfileTab.selectElementInList("address");
cy.get("#kc-attributeGroup").click();
cy.get("button.pf-c-select__menu-item").contains("contact").click();
userProfileTab.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
);
.selectElementInList(attrName)
.setAttributeGroup(group)
.saveAttributeCreation()
.assertNotificationSaved();
// Create user
sidebarPage.goToUsers();
createUserPage.goToCreateUser();
cy.findByTestId("username").type("testuser13");
cy.get("h1#contact").should("have.text", "contact");
cy.get(".pf-c-form__label-text").contains("address").should("exist");
cy.findByTestId("address").type("MyNewAddress1");
cy.findByTestId("create-user").click();
masthead.checkNotificationMessage("The user has been created");
cy.findByTestId("address").should("have.value", "MyNewAddress1");
const initialAttrValue = "MyNewAddress1";
createUserPage
.goToCreateUser()
.assertGroupDisplayName(group, group)
.assertAttributeLabel(attrName, attrName)
.setUsername("testuser13")
.setAttributeValue(attrName, initialAttrValue)
.create()
.assertNotificationCreated()
.assertAttributeValue(attrName, initialAttrValue);
// Edit attribute
cy.findByTestId("address").clear();
cy.findByTestId("address").type("MyNewAddress2");
cy.findByTestId("save-user").click();
masthead.checkNotificationMessage("The user has been saved");
cy.findByTestId("address").should("have.value", "MyNewAddress2");
const newAttrValue = "MyNewAddress2";
createUserPage
.setAttributeValue(attrName, newAttrValue)
.update()
.assertNotificationUpdated()
.assertAttributeValue(attrName, newAttrValue);
sidebarPage.goToRealmSettings();
getUserProfileTab();
getAttributesTab();
userProfileTab.selectElementInList("address");
cy.get("#kc-attributeGroup").click();
cy.get("button.pf-c-select__menu-item").contains("None").click();
userProfileTab.saveAttributeCreation();
masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
userProfileTab
.selectElementInList(attrName)
.resetAttributeGroup()
.saveAttributeCreation()
.assertNotificationSaved();
});
it("Checks that attribute with select-annotation is displayed and editable when user is created/edited", () => {
const userName = "select-test-user";
const attrName = "select-test-attr";
const opt1 = "opt1";
const opt2 = "opt2";
const supportedOptions = [opt1, opt2];
getUserProfileTab();
createAttributeDefinition(attrName, (attrConfigurer) =>
attrConfigurer
.setAllAttributePermissions()
.clickAddValidator()
.selectValidatorType("options")
.setListFieldValues("options", supportedOptions)
.clickSave(),
);
getAttributesGroupTab();
listingPage.deleteItem("contact");
modalUtils.confirmModal();
listingPage.checkEmptyList();
// Create user
sidebarPage.goToUsers();
createUserPage
.goToCreateUser()
.assertAttributeLabel(attrName, attrName)
.assertAttributeSelect(attrName, supportedOptions, "")
.setUsername(userName)
.setAttributeValueOnSelect(attrName, opt1)
.create()
.assertNotificationCreated()
.assertAttributeLabel(attrName, attrName)
.assertAttributeSelect(attrName, supportedOptions, opt1);
// Edit attribute
createUserPage
.setAttributeValueOnSelect(attrName, opt2)
.update()
.assertNotificationUpdated()
.assertAttributeLabel(attrName, attrName)
.assertAttributeSelect(attrName, supportedOptions, opt2);
});
});
function createAttributeDefinition(
attrName: string,
attrConfigurer?: (attrConfigurer: UserProfile) => void,
) {
userProfileTab
.goToAttributesTab()
.clickOnCreateAttributeButton()
.setAttributeNames(attrName, attrName);
if (attrConfigurer) {
attrConfigurer(userProfileTab);
}
userProfileTab.saveAttributeCreation().assertNotificationSaved();
}
});

View file

@ -73,7 +73,7 @@ describe("User creation", () => {
createUserPage.createUser(itemId);
createUserPage.save();
createUserPage.create();
masthead.checkNotificationMessage("The user has been created");
});
@ -95,7 +95,7 @@ describe("User creation", () => {
createUserPage.joinGroups();
createUserPage.save();
createUserPage.create();
masthead.checkNotificationMessage("The user has been created");
});
@ -109,7 +109,7 @@ describe("User creation", () => {
createUserPage.createUser(itemIdWithCred);
userDetailsPage.fillUserData();
createUserPage.save();
createUserPage.create();
masthead.checkNotificationMessage("The user has been created");
sidebarPage.waitForPageLoad();
@ -493,7 +493,7 @@ describe("User creation", () => {
createUserPage.goToCreateUser();
createUserPage.createUser(a11yUser);
userDetailsPage.fillUserData();
createUserPage.save();
createUserPage.create();
cy.checkA11y();
});

View file

@ -1,26 +1,27 @@
export default class FormValidation {
static assertRequired(chain: Cypress.Chainable<JQuery<HTMLElement>>) {
return this.#getHelperText(chain).should("have.text", "Required field");
return this.assertMessage(chain, "Required field");
}
static assertMessage(
chain: Cypress.Chainable<JQuery<HTMLElement>>,
expectedMessage: string,
) {
return this.#getHelperText(chain).should("have.text", expectedMessage);
}
static assertMinValue(
chain: Cypress.Chainable<JQuery<HTMLElement>>,
minValue: number,
) {
this.#getHelperText(chain).should(
"have.text",
`Must be greater than ${minValue}`,
);
this.assertMessage(chain, `Must be greater than ${minValue}`);
}
static assertMaxValue(
chain: Cypress.Chainable<JQuery<HTMLElement>>,
maxValue: number,
) {
this.#getHelperText(chain).should(
"have.text",
`Must be less than ${maxValue}`,
);
this.assertMessage(chain, `Must be less than ${maxValue}`);
}
static #getHelperText(chain: Cypress.Chainable<JQuery<HTMLElement>>) {

View file

@ -71,6 +71,7 @@ export default class RealmSettingsPage extends CommonPage {
forgotPwdSwitch = "forgot-pw-switch";
rememberMeSwitch = "remember-me-switch";
emailAsUsernameSwitch = "email-as-username-switch";
editUsernameSwitch = "edit-username-switch";
loginWithEmailSwitch = "login-with-email-switch";
duplicateEmailsSwitch = "duplicate-emails-switch";
verifyEmailSwitch = "verify-email-switch";
@ -448,6 +449,22 @@ export default class RealmSettingsPage extends CommonPage {
return this;
}
assertSwitch(switchName: string, on: boolean) {
cy.findByTestId(switchName).should("have.value", on ? "on" : "off");
return this;
}
setSwitch(switchName: string, on: boolean) {
if (on) {
cy.findByTestId(switchName).check({ force: true });
} else {
cy.findByTestId(switchName).uncheck({ force: true });
}
return this;
}
toggleCheck(switchName: string) {
cy.findByTestId(switchName).click();

View file

@ -1,6 +1,10 @@
import Select from "../../../../forms/Select";
import Masthead from "../../Masthead";
import ValidatorConfigDialogue from "./ValidatorConfigDialogue";
export default class UserProfile {
readonly masthead = new Masthead();
readonly validatorConfigDialogue = new ValidatorConfigDialogue(this);
#userProfileTab = "rs-user-profile-tab";
#attributesTab = "attributesTab";
#attributesGroupTab = "attributesGroupTab";
@ -13,25 +17,22 @@ export default class UserProfile {
#newAttributeNameInput = "attribute-name";
#newAttributeDisplayNameInput = "attribute-display-name";
#newAttributeEnabledWhen = 'input[name="enabledWhen"]';
#newAttributeRequiredWhen = 'input[name="requiredWhen"]';
#newAttributeEmptyValidators = ".kc-emptyValidators";
#newAttributeAnnotationBtn = "annotations-add-row";
#newAttributeAnnotationKey = "annotations.0.key";
#newAttributeAnnotationValue = "annotations.0.value";
#validatorRolesList = "#validator";
#validatorsList = 'tbody [data-label="name"]';
#saveNewAttributeBtn = "attribute-create";
#addValidatorBtn = "addValidator";
#saveValidatorBtn = "save-validator-role-button";
#removeValidatorBtn = "deleteValidator";
#deleteValidatorBtn = "confirm";
#cancelAddingValidatorBtn = "cancel-validator-role-button";
#cancelRemovingValidatorBtn = "cancel";
#newAttributeRequiredField = "input#kc-required.pf-c-switch__input";
#newAttributeUserEdit = "user-edit";
#newAttributeAdminEdit = "admin-edit";
#newAttributeUserView = "user-view";
#newAttributeAdminView = "admin-view";
#createAttributesGroupButton = "create-attributes-groups-action";
#newAttributesGroupNameInput = "input#kc-name";
#newAttributesGroupDisplayNameInput = 'input[name="displayHeader"]';
#saveNewAttributesGroupBtn = "saveGroupBtn";
@ -56,7 +57,7 @@ export default class UserProfile {
return this;
}
createAttributeButtonClick() {
clickOnCreateAttributeButton() {
cy.findByTestId(this.#createAttributeButton).click();
return this;
}
@ -81,7 +82,7 @@ export default class UserProfile {
return this;
}
createAttribute(name: string, displayName: string) {
setAttributeNames(name: string, displayName: string) {
cy.findByTestId(this.#newAttributeNameInput).type(name);
cy.findByTestId(this.#newAttributeDisplayNameInput).type(displayName);
return this;
@ -97,23 +98,21 @@ export default class UserProfile {
return this;
}
createAttributeNotRequiredWithPermissions(name: string, displayName: string) {
cy.findByTestId(this.#newAttributeNameInput).type(name);
cy.findByTestId(this.#newAttributeDisplayNameInput).type(displayName);
cy.get(this.#newAttributeEnabledWhen).first().check();
cy.findByTestId(this.#newAttributeUserEdit).first().check({ force: true });
cy.findByTestId(this.#newAttributeUserView).first().check({ force: true });
cy.findByTestId(this.#newAttributeAdminView).first().check({ force: true });
setAttributeRequired() {
cy.get(this.#newAttributeRequiredField).first().check({ force: true });
return this;
}
createAttributeNotRequiredWithoutPermissions(
name: string,
displayName: string,
) {
cy.findByTestId(this.#newAttributeNameInput).type(name);
cy.findByTestId(this.#newAttributeDisplayNameInput).type(displayName);
cy.get(this.#newAttributeEnabledWhen).first().check();
setAllAttributePermissions() {
cy.findByTestId(this.#newAttributeUserEdit).first().check({ force: true });
cy.findByTestId(this.#newAttributeUserView).first().check({ force: true });
cy.findByTestId(this.#newAttributeAdminView).first().check({ force: true });
return this;
}
setNoAttributePermissions() {
cy.findByTestId(this.#newAttributeAdminEdit)
.first()
.uncheck({ force: true });
@ -121,15 +120,8 @@ export default class UserProfile {
return this;
}
createAttributeRequiredWithPermissions(name: string, displayName: string) {
cy.findByTestId(this.#newAttributeNameInput).type(name);
cy.findByTestId(this.#newAttributeDisplayNameInput).type(displayName);
cy.get(this.#newAttributeEnabledWhen).first().check();
cy.get(this.#newAttributeRequiredField).first().check({ force: true });
cy.get(this.#newAttributeRequiredWhen).first().check({ force: true });
cy.findByTestId(this.#newAttributeUserEdit).first().check({ force: true });
cy.findByTestId(this.#newAttributeUserView).first().check({ force: true });
cy.findByTestId(this.#newAttributeAdminView).first().check({ force: true });
clickOnCreatesAttributesGroupButton() {
cy.findByTestId(this.#createAttributesGroupButton).click();
return this;
}
@ -149,6 +141,17 @@ export default class UserProfile {
return this;
}
setAttributeGroup(group: string) {
cy.get("#kc-attributeGroup").click();
cy.get("button.pf-c-select__menu-item").contains(group).click();
return this;
}
resetAttributeGroup() {
return this.setAttributeGroup("None");
}
editAttribute(displayName: string) {
cy.findByTestId(this.#newAttributeDisplayNameInput)
.click()
@ -162,10 +165,9 @@ export default class UserProfile {
return this;
}
addValidator() {
cy.findByTestId(this.#addValidatorBtn).click();
Select.selectItem(cy.get(this.#validatorRolesList), "email");
cy.findByTestId(this.#saveValidatorBtn).click();
addValidator(type: string) {
this.clickAddValidator().selectValidatorType(type).clickSave();
return this;
}
@ -175,13 +177,18 @@ export default class UserProfile {
return this;
}
cancelAddingValidator() {
cy.findByTestId(this.#addValidatorBtn).click();
Select.selectItem(cy.get(this.#validatorRolesList), "email");
cy.findByTestId(this.#cancelAddingValidatorBtn).click();
cancelAddingValidator(type: string) {
this.clickAddValidator().selectValidatorType(type).clickCancel();
return this;
}
clickAddValidator() {
cy.findByTestId(this.#addValidatorBtn).click();
return this.validatorConfigDialogue;
}
cancelRemovingValidator() {
cy.findByTestId(this.#removeValidatorBtn).click();
cy.findByTestId(this.#cancelRemovingValidatorBtn).click();
@ -201,6 +208,14 @@ export default class UserProfile {
return this;
}
assertNotificationSaved() {
this.masthead.checkNotificationMessage(
"Success! User Profile configuration has been saved.",
);
return this;
}
shouldHaveText(text: string) {
this.#getText().should("have.text", text);
return this;

View file

@ -0,0 +1,46 @@
import UserProfile from "./UserProfile";
import Select from "../../../../forms/Select";
export default class ValidatorConfigDialogue {
readonly #validatorSelector = "#validator";
readonly #saveValidatorButton = "save-validator-role-button";
readonly #cancelValidatorButton = "cancel-validator-role-button";
readonly #addValue = "addValue";
readonly userProfile: UserProfile;
constructor(userProfile: UserProfile) {
this.userProfile = userProfile;
}
clickSave() {
cy.findByTestId(this.#saveValidatorButton).click();
return this.userProfile;
}
selectValidatorType(type: string) {
Select.selectItem(cy.get(this.#validatorSelector), type);
return this;
}
setListFieldValues(fieldName: string, values: string[]) {
for (let i = 0; i < values.length; i++) {
if (i != 0) {
cy.findByTestId(this.#addValue).click();
}
const testId = `config.options${i}`;
cy.findByTestId(testId).clear().type(values[i]);
}
return this;
}
clickCancel() {
cy.findByTestId(this.#cancelValidatorButton).click();
return this.userProfile;
}
}

View file

@ -1,34 +1,33 @@
import Masthead from "../../Masthead";
import FormValidation from "../../../../forms/FormValidation";
export default class CreateUserPage {
usernameInput: string;
readonly masthead = new Masthead();
readonly emptyOptionValue = "Choose...";
usersEmptyState: string;
emptyStateCreateUserBtn: string;
addUserBtn: string;
joinGroupsBtn: string;
joinBtn: string;
createBtn: string;
saveBtn: string;
cancelBtn: string;
constructor() {
this.usernameInput = "#username";
this.usersEmptyState = "empty-state";
this.emptyStateCreateUserBtn = "no-users-found-empty-action";
this.addUserBtn = "add-user";
this.joinGroupsBtn = "join-groups-button";
this.joinBtn = "join-button";
this.saveBtn = "create-user";
this.createBtn = "create-user";
this.saveBtn = "save-user";
this.cancelBtn = "cancel-create-user";
}
//#region General Settings
createUser(username: string) {
cy.get(this.usernameInput).clear();
if (username) {
cy.get(this.usernameInput).type(username);
}
return this;
return this.setUsername(username);
}
goToCreateUser() {
@ -55,12 +54,177 @@ export default class CreateUserPage {
return this;
}
save() {
create() {
cy.findByTestId(this.createBtn).click();
return this;
}
update() {
cy.findByTestId(this.saveBtn).click();
return this;
}
assertAttributeValue(attrName: string, expectedValue: string) {
cy.findByTestId(attrName).should("have.value", expectedValue);
return this;
}
assertAttributeFieldExists(attrName: string, shouldExist: boolean) {
const chainer = shouldExist ? "exist" : "not.exist";
cy.findByTestId(attrName).should(chainer);
return this;
}
assertAttributeSelect(
attrName: string,
expectedOptionsWithoutEmptyOption: string[],
expectedValue: string,
) {
this.#getSelectFieldButton(attrName).should(
"have.class",
"pf-c-select__toggle",
);
const valueToCheck = expectedValue ? expectedValue : this.emptyOptionValue;
this.#getSelectFieldButton(attrName)
.find(".pf-c-select__toggle-text")
.invoke("text")
.should("eq", valueToCheck);
const expectedOptions = [this.emptyOptionValue].concat(
expectedOptionsWithoutEmptyOption,
);
this.#withSelectExpanded(attrName, () => {
this.#getSelectOptions(attrName)
.should("have.length", expectedOptions.length)
.each(($option, index) =>
cy.wrap($option).should("have.text", expectedOptions[index]),
);
});
return this;
}
#getSelectFieldButton(attrName: string) {
const attrSelector = `#${attrName}`;
return cy.get(attrSelector);
}
#getSelectOptions(attrName: string) {
return this.#getSelectFieldButton(attrName)
.parent()
.find(".pf-c-select__menu-item");
}
#toggleSelectField(
attrName: string,
toggleCondition?: (currentlyExpanded: boolean) => boolean,
) {
return this.#getSelectFieldButton(attrName).then(($selectField) => {
const currentlyExpanded = $selectField.attr("aria-expanded") === "true";
if (!toggleCondition || toggleCondition(currentlyExpanded)) {
cy.wrap($selectField).click();
}
});
}
/**
* Runs the given function in the context of an expanded select field.
*
* This method makes sure that the initial expanded/collapsed state is preserved:
* The select field will be expanded before running the function, if it is not already expanded.
* It will be collapsed after running the function, when it was not expanded before running the function.
*
* @param attrName the attribute name of the select field
* @param func the function to be applied
* @private
*/
#withSelectExpanded(attrName: string, func: () => any) {
let wasInitiallyExpanded = false;
this.#toggleSelectField(attrName, (currentlyExpanded) => {
wasInitiallyExpanded = currentlyExpanded;
return !currentlyExpanded;
})
.then(() => func())
.then(() =>
// click again on the dropdown to hide the values list, when necessary
this.#toggleSelectField(
attrName,
(currentlyExpanded) => currentlyExpanded && !wasInitiallyExpanded,
),
);
}
assertAttributeLabel(attrName: string, expectedText: string) {
cy.get(`.pf-c-form__label[for='${attrName}'] .pf-c-form__label-text`)
.contains(expectedText)
.should("exist");
return this;
}
assertValidationErrorRequired(attrName: string) {
FormValidation.assertMessage(
cy.findByTestId(attrName),
`Please specify '${attrName}'.`,
);
return this;
}
assertGroupDisplayName(group: string, expectedDisplayName: string) {
cy.get(`h1#${group.toLowerCase()}`).should(
"have.text",
expectedDisplayName,
);
return this;
}
setAttributeValue(attrName: string, value: string) {
cy.findByTestId(attrName).clear().type(value);
return this;
}
setAttributeValueOnSelect(attrName: string, value: string) {
this.#withSelectExpanded(attrName, () => {
this.#getSelectOptions(attrName).contains(value).click();
});
return this;
}
setUsername(value: string) {
this.#getUsernameField().clear();
if (value) {
this.#getUsernameField().type(value);
}
return this;
}
#getUsernameField() {
return cy.findByTestId("username");
}
assertNotificationCreated() {
this.masthead.checkNotificationMessage("The user has been created");
return this;
}
assertNotificationUpdated() {
this.masthead.checkNotificationMessage("The user has been saved");
return this;
}
cancel() {
cy.findByTestId(this.cancelBtn).click();

View file

@ -245,6 +245,18 @@ class AdminClient {
});
}
async getUserProfile(realm: string) {
await this.#login();
return await this.#client.users.getProfile({ realm });
}
async updateUserProfile(realm: string, userProfile: UserProfileConfig) {
await this.#login();
await this.#client.users.updateProfile(merge(userProfile, { realm }));
}
async patchUserProfile(realm: string, payload: UserProfileConfig) {
await this.#login();

View file

@ -75,7 +75,11 @@ export const AttributesGroupTab = () => {
<ToolbarItem>
<Button
component={(props) => (
<Link {...props} to={toNewAttributesGroup({ realm })} />
<Link
data-testid="create-attributes-groups-action"
{...props}
to={toNewAttributesGroup({ realm })}
/>
)}
>
{t("createGroupText")}