diff --git a/js/apps/admin-ui/cypress/e2e/client_registration_policies.spec.ts b/js/apps/admin-ui/cypress/e2e/client_registration_policies.spec.ts index 0cdbc73cdd..6adbf2199d 100644 --- a/js/apps/admin-ui/cypress/e2e/client_registration_policies.spec.ts +++ b/js/apps/admin-ui/cypress/e2e/client_registration_policies.spec.ts @@ -29,10 +29,10 @@ describe("Client registration policies tab", () => { it("add anonymous client registration policy", () => { clientRegistrationPage - .createPolicy() + .createAnonymousPolicy() .selectRow("max-clients") .fillPolicyForm({ - name: "new policy", + name: "newAnonymPolicy1", }) .formUtils() .save(); @@ -41,32 +41,33 @@ describe("Client registration policies tab", () => { "New client policy created successfully", ); clientRegistrationPage.formUtils().cancel(); - listingPage.itemExist("new policy"); + listingPage.itemExist("newAnonymPolicy1"); }); it("edit anonymous client registration policy", () => { - listingPage.goToItemDetails("new policy"); + const policy = "newAnonymPolicy1"; + clientRegistrationPage.findAndSelectInAnonymousPoliciesTable(policy); cy.findByTestId("name").clear(); clientRegistrationPage .fillPolicyForm({ - name: "policy 2", + name: "policy2", }) .formUtils() .save(); masthead.checkNotificationMessage("Client policy updated successfully"); clientRegistrationPage.formUtils().cancel(); - listingPage.itemExist("policy 2"); + listingPage.itemExist("policy2"); }); it("delete anonymous client registration policy", () => { - listingPage.clickRowDetails("policy 2").clickDetailMenu("Delete"); - clientRegistrationPage.modalUtils().confirmModal(); + const policy = "policy2"; + listingPage.deleteItem(policy); + cy.findByTestId("confirm").click(); masthead.checkNotificationMessage( "Client registration policy deleted successfully", ); - listingPage.itemExist("policy 2", false); }); }); @@ -84,10 +85,10 @@ describe("Client registration policies tab", () => { it("add authenticated client registration policy", () => { clientRegistrationPage - .createPolicy() + .createAuthenticatedPolicy() .selectRow("scope") .fillPolicyForm({ - name: "new authenticated policy", + name: "newAuthPolicy1", }) .formUtils() .save(); @@ -96,32 +97,33 @@ describe("Client registration policies tab", () => { "New client policy created successfully", ); clientRegistrationPage.formUtils().cancel(); - listingPage.itemExist("new authenticated policy"); + listingPage.itemExist("newAuthPolicy1"); }); it("edit authenticated client registration policy", () => { - listingPage.goToItemDetails("new authenticated policy"); + const policy = "newAuthPolicy1"; + clientRegistrationPage.findAndSelectInAuthenticatedPoliciesTable(policy); cy.findByTestId("name").clear(); clientRegistrationPage .fillPolicyForm({ - name: "policy 3", + name: "policy3", }) .formUtils() .save(); masthead.checkNotificationMessage("Client policy updated successfully"); clientRegistrationPage.formUtils().cancel(); - listingPage.itemExist("policy 3"); + listingPage.itemExist("policy3"); }); it("delete authenticated client registration policy", () => { - listingPage.clickRowDetails("policy 3").clickDetailMenu("Delete"); - clientRegistrationPage.modalUtils().confirmModal(); + const policy = "policy3"; + listingPage.deleteItem(policy); + cy.findByTestId("confirm").click(); masthead.checkNotificationMessage( "Client registration policy deleted successfully", ); - listingPage.itemExist("policy 3", false); }); }); }); diff --git a/js/apps/admin-ui/cypress/e2e/partial_export_test.spec.ts b/js/apps/admin-ui/cypress/e2e/partial_export_test.spec.ts index 4fd912afb6..92ff4856a5 100644 --- a/js/apps/admin-ui/cypress/e2e/partial_export_test.spec.ts +++ b/js/apps/admin-ui/cypress/e2e/partial_export_test.spec.ts @@ -45,7 +45,7 @@ describe("Partial realm export", () => { it("Exports the realm", () => { modal.includeGroupsAndRolesSwitch().click({ force: true }); - modal.includeGroupsAndRolesSwitch().click({ force: true }); + modal.includeClientsSwitch().click({ force: true }); modal.exportButton().click(); cy.readFile( Cypress.config("downloadsFolder") + "/realm-export.json", diff --git a/js/apps/admin-ui/cypress/e2e/realm_settings_client_profiles_test.spec.ts b/js/apps/admin-ui/cypress/e2e/realm_settings_client_profiles_test.spec.ts index 28dc764e37..63f8811a5e 100644 --- a/js/apps/admin-ui/cypress/e2e/realm_settings_client_profiles_test.spec.ts +++ b/js/apps/admin-ui/cypress/e2e/realm_settings_client_profiles_test.spec.ts @@ -58,6 +58,17 @@ describe("Realm settings client profiles tab tests", () => { realmSettingsPage.searchClientProfile(profileName); }); + it("Should search non-existent client profile", () => { + realmSettingsPage.searchNonExistingClientProfile("nonExistentProfile"); + cy.findByTestId("empty-state").should("be.visible"); + }); + + it("Should navigate to client profile", () => { + realmSettingsPage.searchClientProfile(profileName); + realmSettingsPage.goToClientProfileByNameLink(profileName); + cy.findByTestId("view-header").should("have.text", profileName); + }); + it("Check navigating between Form View and JSON editor", () => { realmSettingsPage.shouldNavigateBetweenFormAndJSONView(); }); diff --git a/js/apps/admin-ui/cypress/e2e/realm_settings_events_test.spec.ts b/js/apps/admin-ui/cypress/e2e/realm_settings_events_test.spec.ts index 274a8e0b0e..25de676ba4 100644 --- a/js/apps/admin-ui/cypress/e2e/realm_settings_events_test.spec.ts +++ b/js/apps/admin-ui/cypress/e2e/realm_settings_events_test.spec.ts @@ -269,33 +269,6 @@ describe("Realm settings events tab tests", () => { cy.findByTestId("localization-tab-save").click(); }); - it("Realm header settings", () => { - sidebarPage.goToRealmSettings(); - cy.findByTestId("rs-security-defenses-tab").click(); - cy.findByTestId("headers-form-tab-save").should("be.disabled"); - cy.get("#xFrameOptions").clear().type("DENY"); - cy.findByTestId("headers-form-tab-save").should("be.enabled").click(); - - masthead.checkNotificationMessage("Realm successfully updated"); - }); - - it("Brute force detection", () => { - sidebarPage.goToRealmSettings(); - cy.findAllByTestId("rs-security-defenses-tab").click(); - cy.get("#pf-tab-20-bruteForce").click(); - - cy.findByTestId("brute-force-tab-save").should("be.disabled"); - - cy.get("#bruteForceProtected").click({ force: true }); - cy.findByTestId("waitIncrementSeconds").type("1"); - cy.findByTestId("maxFailureWaitSeconds").type("1"); - cy.findByTestId("maxDeltaTimeSeconds").type("1"); - cy.findByTestId("minimumQuickLoginWaitSeconds").type("1"); - - cy.findByTestId("brute-force-tab-save").should("be.enabled").click(); - masthead.checkNotificationMessage("Realm successfully updated"); - }); - it("add session data", () => { sidebarPage.goToRealmSettings(); diff --git a/js/apps/admin-ui/cypress/e2e/realm_settings_general_tab_test.spec.ts b/js/apps/admin-ui/cypress/e2e/realm_settings_general_tab_test.spec.ts index 8d221ea777..9d148767aa 100644 --- a/js/apps/admin-ui/cypress/e2e/realm_settings_general_tab_test.spec.ts +++ b/js/apps/admin-ui/cypress/e2e/realm_settings_general_tab_test.spec.ts @@ -61,6 +61,13 @@ describe("Realm settings general tab tests", () => { masthead.checkNotificationMessage("Realm successfully updated"); }); + it("Fail to set Realm ID to empty", () => { + sidebarPage.goToRealmSettings(); + realmSettingsPage.clearRealmId(); + realmSettingsPage.saveGeneral(); + cy.get("#kc-realm-id-helper").should("have.text", "Required field"); + }); + it("Modify Display name", () => { sidebarPage.goToRealmSettings(); realmSettingsPage.fillDisplayName("display_name"); diff --git a/js/apps/admin-ui/cypress/e2e/realm_settings_tabs_test.spec.ts b/js/apps/admin-ui/cypress/e2e/realm_settings_tabs_test.spec.ts index 41ae7000a3..7f1e125bd9 100644 --- a/js/apps/admin-ui/cypress/e2e/realm_settings_tabs_test.spec.ts +++ b/js/apps/admin-ui/cypress/e2e/realm_settings_tabs_test.spec.ts @@ -131,6 +131,42 @@ describe("Realm settings tabs tests", () => { realmSettingsPage.saveThemes(); }); + describe("Go to security defenses tab", () => { + it("Realm header settings- update single input", () => { + sidebarPage.goToRealmSettings(); + realmSettingsPage.goToSecurityDefensesTab(); + cy.get("#xFrameOptions").clear().type("DENY"); + realmSettingsPage.saveSecurityDefensesHeaders(); + masthead.checkNotificationMessage("Realm successfully updated"); + }); + it("Realm header settings- update all inputs", () => { + sidebarPage.goToRealmSettings(); + realmSettingsPage.goToSecurityDefensesTab(); + cy.get("#xFrameOptions").clear().type("SAMEORIGIN"); + cy.get("#contentSecurityPolicy").clear().type("default-src 'self'"); + cy.get("#strictTransportSecurity").clear().type("max-age=31536000"); + cy.get("#xContentTypeOptions").clear().type("nosniff"); + cy.get("#xRobotsTag").clear().type("none"); + cy.get("#xXSSProtection").clear().type("1; mode=block"); + cy.get("#strictTransportSecurity").clear().type("max-age=31537000"); + cy.get("#referrerPolicy").clear().type("referrer"); + realmSettingsPage.saveSecurityDefensesHeaders(); + masthead.checkNotificationMessage("Realm successfully updated"); + }); + it("Brute force detection- update values", () => { + sidebarPage.goToRealmSettings(); + realmSettingsPage.goToSecurityDefensesTab(); + realmSettingsPage.goToSecurityDefensesBruteForceTab(); + cy.get("#bruteForceProtected").click({ force: true }); + cy.findByTestId("waitIncrementSeconds").type("1"); + cy.findByTestId("maxFailureWaitSeconds").type("1"); + cy.findByTestId("maxDeltaTimeSeconds").type("1"); + cy.findByTestId("minimumQuickLoginWaitSeconds").type("1"); + realmSettingsPage.saveSecurityDefensesBruteForce(); + masthead.checkNotificationMessage("Realm successfully updated"); + }); + }); + describe("Accessibility tests for realm settings", () => { beforeEach(() => { loginPage.logIn(); diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/clients/ClientRegistrationPage.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/clients/ClientRegistrationPage.ts index bd7db4fa04..62c1d52063 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/clients/ClientRegistrationPage.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/clients/ClientRegistrationPage.ts @@ -16,6 +16,30 @@ export class ClientRegistrationPage extends CommonPage { return this; } + createAnonymousPolicy() { + cy.findByTestId("createPolicy-anonymous").click(); + return this; + } + + createAuthenticatedPolicy() { + cy.findByTestId("createPolicy-authenticated").click(); + return this; + } + + findAndSelectInAnonymousPoliciesTable(policy: string) { + cy.findByTestId("clientRegistration-anonymous") + .find("tr") + .contains(policy) + .click(); + } + + findAndSelectInAuthenticatedPoliciesTable(policy: string) { + cy.findByTestId("clientRegistration-authenticated") + .find("tr") + .contains(policy) + .click(); + } + selectRow(name: string) { cy.findAllByTestId(name).click(); return this; diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts index cc7699382f..c5e7e52574 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/realm_settings/RealmSettingsPage.ts @@ -239,6 +239,12 @@ export default class RealmSettingsPage extends CommonPage { #publicKeyBtn = ".kc-keys-list > tbody > tr > td > .button-wrapper > button"; #realmSettingsEventsTab = new RealmSettingsEventsTab(); + #realmId = 'input[aria-label="Copyable input"]'; + #securityDefensesHeadersSaveBtn = "headers-form-tab-save"; + #securityDefensesBruteForceSaveBtn = "brute-force-tab-save"; + #securityDefensesHeadersTab = "security-defenses-headers-tab"; + #securityDefensesBruteForceTab = "security-defenses-brute-force-tab"; + #clientProfileLink = 'table[aria-label="Profiles"] tbody a'; #realmName?: string; constructor(realmName?: string) { @@ -313,6 +319,10 @@ export default class RealmSettingsPage extends CommonPage { cy.get(this.#realmDisplayName).clear().type(displayName); } + clearRealmId() { + cy.get(this.#realmId).clear(); + } + fillFromDisplayName(displayName: string) { cy.findByTestId(this.#fromDisplayName).clear().type(displayName); } @@ -1043,6 +1053,11 @@ export default class RealmSettingsPage extends CommonPage { return this; } + searchNonExistingClientProfile(name: string) { + new ListingPage().searchItem(name, false); + return this; + } + shouldNotHaveConditionsConfigured() { cy.get(this.#clientPolicy).click(); cy.get('h2[class*="kc-emptyConditions"]').should( @@ -1250,6 +1265,24 @@ export default class RealmSettingsPage extends CommonPage { return this; } + saveSecurityDefensesHeaders() { + cy.findByTestId(this.#securityDefensesHeadersSaveBtn).click(); + } + + saveSecurityDefensesBruteForce() { + cy.findByTestId(this.#securityDefensesBruteForceSaveBtn).click(); + } + + goToSecurityDefensesHeadersTab() { + cy.findByTestId(this.#securityDefensesHeadersTab).click(); + return this; + } + + goToSecurityDefensesBruteForceTab() { + cy.findByTestId(this.#securityDefensesBruteForceTab).click(); + return this; + } + goToSessionsTab() { cy.findByTestId(this.sessionsTab).click(); return this; @@ -1259,4 +1292,9 @@ export default class RealmSettingsPage extends CommonPage { cy.findByTestId(this.tokensTab).click(); return this; } + + goToClientProfileByNameLink(profileName: string) { + cy.get(this.#clientProfileLink).contains(profileName).click(); + return this; + } } diff --git a/js/apps/admin-ui/src/clients/registration/ClientRegistrationList.tsx b/js/apps/admin-ui/src/clients/registration/ClientRegistrationList.tsx index 4ac8cd0e78..42084b7ca8 100644 --- a/js/apps/admin-ui/src/clients/registration/ClientRegistrationList.tsx +++ b/js/apps/admin-ui/src/clients/registration/ClientRegistrationList.tsx @@ -109,7 +109,10 @@ export const ClientRegistrationList = ({ loader={policies} toolbarItem={ - diff --git a/js/apps/admin-ui/src/realm-settings/security-defences/SecurityDefenses.tsx b/js/apps/admin-ui/src/realm-settings/security-defences/SecurityDefenses.tsx index 07632a02ae..c28c70c117 100644 --- a/js/apps/admin-ui/src/realm-settings/security-defences/SecurityDefenses.tsx +++ b/js/apps/admin-ui/src/realm-settings/security-defences/SecurityDefenses.tsx @@ -22,6 +22,7 @@ export const SecurityDefenses = ({ realm, save }: SecurityDefensesProps) => { {t("headers")}} > @@ -31,6 +32,7 @@ export const SecurityDefenses = ({ realm, save }: SecurityDefensesProps) => { {t("bruteForceDetection")}} >