Created more tests for the authentication flow (#2633)
This commit is contained in:
parent
cc7ec1cf7f
commit
d8d28e1d7c
7 changed files with 125 additions and 89 deletions
|
@ -8,38 +8,57 @@ import FlowDetails from "../support/pages/admin_console/manage/authentication/Fl
|
|||
import RequiredActions from "../support/pages/admin_console/manage/authentication/RequiredActions";
|
||||
import adminClient from "../support/util/AdminClient";
|
||||
import PasswordPolicies from "../support/pages/admin_console/manage/authentication/PasswordPolicies";
|
||||
import ModalUtils from "../support/util/ModalUtils";
|
||||
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
const sidebarPage = new SidebarPage();
|
||||
const listingPage = new ListingPage();
|
||||
|
||||
describe("Authentication test", () => {
|
||||
const loginPage = new LoginPage();
|
||||
const masthead = new Masthead();
|
||||
const sidebarPage = new SidebarPage();
|
||||
const listingPage = new ListingPage();
|
||||
|
||||
const detailPage = new FlowDetails();
|
||||
const duplicateFlowModal = new DuplicateFlowModal();
|
||||
const modalUtil = new ModalUtils();
|
||||
|
||||
beforeEach(() => {
|
||||
before(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.waitForPageLoad();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
sidebarPage.goToAuthentication();
|
||||
});
|
||||
|
||||
it("should create duplicate of existing flow", () => {
|
||||
const modalDialog = new DuplicateFlowModal();
|
||||
listingPage.clickRowDetails("Browser").clickDetailMenu("Duplicate");
|
||||
modalDialog.fill("Copy of browser");
|
||||
duplicateFlowModal.fill("Copy of browser");
|
||||
|
||||
masthead.checkNotificationMessage("Flow successfully duplicated");
|
||||
listingPage.itemExist("Copy of browser");
|
||||
});
|
||||
|
||||
it("Should fail duplicate with empty flow name", () => {
|
||||
listingPage.clickRowDetails("Browser").clickDetailMenu("Duplicate");
|
||||
duplicateFlowModal.fill().shouldShowError("Required field");
|
||||
modalUtil.cancelModal();
|
||||
});
|
||||
|
||||
it("Should fail duplicate with duplicated name", () => {
|
||||
listingPage.clickRowDetails("Browser").clickDetailMenu("Duplicate");
|
||||
duplicateFlowModal.fill("browser");
|
||||
masthead.checkNotificationMessage(
|
||||
"Could not duplicate flow: New flow alias name already exists"
|
||||
);
|
||||
});
|
||||
|
||||
it("should show the details of a flow as a table", () => {
|
||||
listingPage.goToItemDetails("Copy of browser");
|
||||
|
||||
detailPage.executionExists("Cookie");
|
||||
});
|
||||
|
||||
it("should move kerberos down", () => {
|
||||
it.skip("should move kerberos down", () => {
|
||||
listingPage.goToItemDetails("Copy of browser");
|
||||
|
||||
detailPage.moveRowTo("Kerberos", "Identity Provider Redirector");
|
||||
|
@ -94,6 +113,13 @@ describe("Authentication test", () => {
|
|||
detailPage.flowExists(flowName);
|
||||
});
|
||||
|
||||
it("Should remove an execution", () => {
|
||||
listingPage.goToItemDetails("Copy of browser");
|
||||
detailPage.executionExists("Cookie").clickRowDelete("Cookie");
|
||||
modalUtil.confirmModal();
|
||||
detailPage.executionExists("Cookie", false);
|
||||
});
|
||||
|
||||
it("should create flow from scratch", () => {
|
||||
const flowName = "Flow";
|
||||
listingPage.goToCreateItem();
|
||||
|
@ -109,78 +135,76 @@ describe("Authentication test", () => {
|
|||
|
||||
detailPage.flowExists(flowName);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Required actions", () => {
|
||||
const requiredActionsPage = new RequiredActions();
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToRealm("Test");
|
||||
sidebarPage.goToAuthentication();
|
||||
requiredActionsPage.goToTab();
|
||||
});
|
||||
describe("Required actions", () => {
|
||||
const requiredActionsPage = new RequiredActions();
|
||||
|
||||
before(() => {
|
||||
adminClient.createRealm("Test");
|
||||
});
|
||||
|
||||
after(() => {
|
||||
adminClient.deleteRealm("Test");
|
||||
});
|
||||
|
||||
it("should enable delete account", () => {
|
||||
const action = "Delete Account";
|
||||
requiredActionsPage.enableAction(action);
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
requiredActionsPage.isChecked(action);
|
||||
});
|
||||
|
||||
it("should register an unregistered action", () => {
|
||||
const action = "Verify Profile";
|
||||
requiredActionsPage.enableAction(action);
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
requiredActionsPage.isChecked(action).isDefaultEnabled(action);
|
||||
});
|
||||
|
||||
it("should set action as default", () => {
|
||||
const action = "Configure OTP";
|
||||
requiredActionsPage.setAsDefault(action);
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
requiredActionsPage.isDefaultChecked(action);
|
||||
});
|
||||
|
||||
it("should reorder required actions", () => {
|
||||
const action = "Terms and Conditions";
|
||||
requiredActionsPage.moveRowTo(action, "Update Profile");
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
});
|
||||
before(() => {
|
||||
cy.wrap(adminClient.createRealm("Test"));
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToRealm("Test");
|
||||
});
|
||||
|
||||
describe("Password policies tab", () => {
|
||||
const passwordPoliciesPage = new PasswordPolicies();
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToAuthentication();
|
||||
passwordPoliciesPage.goToTab();
|
||||
});
|
||||
beforeEach(() => {
|
||||
sidebarPage.goToAuthentication();
|
||||
requiredActionsPage.goToTab();
|
||||
});
|
||||
|
||||
it("should add password policies", () => {
|
||||
passwordPoliciesPage
|
||||
.shouldShowEmptyState()
|
||||
.addPolicy("Not Recently Used")
|
||||
.save();
|
||||
masthead.checkNotificationMessage(
|
||||
"Password policies successfully updated"
|
||||
);
|
||||
});
|
||||
after(() => {
|
||||
adminClient.deleteRealm("Test");
|
||||
});
|
||||
|
||||
it("should remove password policies", () => {
|
||||
passwordPoliciesPage.removePolicy("remove-passwordHistory").save();
|
||||
masthead.checkNotificationMessage(
|
||||
"Password policies successfully updated"
|
||||
);
|
||||
passwordPoliciesPage.shouldShowEmptyState();
|
||||
});
|
||||
it("should enable delete account", () => {
|
||||
const action = "Delete Account";
|
||||
requiredActionsPage.enableAction(action);
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
requiredActionsPage.isChecked(action);
|
||||
});
|
||||
|
||||
it("should register an unregistered action", () => {
|
||||
const action = "Verify Profile";
|
||||
requiredActionsPage.enableAction(action);
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
requiredActionsPage.isChecked(action).isDefaultEnabled(action);
|
||||
});
|
||||
|
||||
it("should set action as default", () => {
|
||||
const action = "Configure OTP";
|
||||
requiredActionsPage.setAsDefault(action);
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
requiredActionsPage.isDefaultChecked(action);
|
||||
});
|
||||
|
||||
it("should reorder required actions", () => {
|
||||
const action = "Terms and Conditions";
|
||||
requiredActionsPage.moveRowTo(action, "Update Profile");
|
||||
masthead.checkNotificationMessage("Updated required action successfully");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Password policies tab", () => {
|
||||
const passwordPoliciesPage = new PasswordPolicies();
|
||||
|
||||
beforeEach(() => {
|
||||
keycloakBefore();
|
||||
loginPage.logIn();
|
||||
sidebarPage.goToAuthentication();
|
||||
passwordPoliciesPage.goToTab();
|
||||
});
|
||||
|
||||
it("should add password policies", () => {
|
||||
passwordPoliciesPage
|
||||
.shouldShowEmptyState()
|
||||
.addPolicy("Not Recently Used")
|
||||
.save();
|
||||
masthead.checkNotificationMessage("Password policies successfully updated");
|
||||
});
|
||||
|
||||
it("should remove password policies", () => {
|
||||
passwordPoliciesPage.removePolicy("remove-passwordHistory").save();
|
||||
masthead.checkNotificationMessage("Password policies successfully updated");
|
||||
passwordPoliciesPage.shouldShowEmptyState();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,14 +2,20 @@ export default class DuplicateFlowModal {
|
|||
private aliasInput = "alias";
|
||||
private descriptionInput = "description";
|
||||
private confirmButton = "confirm";
|
||||
private errorText = ".pf-m-error";
|
||||
|
||||
fill(name?: string, description?: string) {
|
||||
cy.findByTestId(this.aliasInput).clear();
|
||||
if (name) {
|
||||
cy.findByTestId(this.aliasInput).clear().type(name);
|
||||
cy.findByTestId(this.aliasInput).type(name);
|
||||
if (description) cy.get(this.descriptionInput).type(description);
|
||||
}
|
||||
|
||||
cy.findByTestId(this.confirmButton).click();
|
||||
return this;
|
||||
}
|
||||
|
||||
shouldShowError(message: string) {
|
||||
cy.get(this.errorText).invoke("text").should("contain", message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
type RequirementType = "Required" | "Alternative" | "Disabled" | "Conditional";
|
||||
|
||||
export default class FlowDetails {
|
||||
executionExists(name: string) {
|
||||
this.getExecution(name).should("exist");
|
||||
executionExists(name: string, exist = true) {
|
||||
this.getExecution(name).should((!exist ? "not." : "") + "exist");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,12 @@ export default class FlowDetails {
|
|||
return this;
|
||||
}
|
||||
|
||||
clickRowDelete(name: string) {
|
||||
cy.findByTestId(`${name}-delete`).click();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private fillSubFlowModal(subFlowName: string, name: string) {
|
||||
cy.get(".pf-c-modal-box__title-text").contains(
|
||||
"Add step to " + subFlowName
|
||||
|
|
|
@ -41,7 +41,7 @@ export const DuplicateFlowModal = ({
|
|||
}, [name, description, setValue]);
|
||||
|
||||
const save = async () => {
|
||||
await trigger();
|
||||
if (!(await trigger())) return;
|
||||
const form = getValues();
|
||||
try {
|
||||
await adminClient.authenticationManagement.copyFlow({
|
||||
|
|
|
@ -130,13 +130,13 @@ export default function FlowDetails() {
|
|||
}
|
||||
};
|
||||
|
||||
const update = async (
|
||||
execution: AuthenticationExecutionInfoRepresentation
|
||||
) => {
|
||||
const update = async (execution: ExpandableExecution) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { executionList, isCollapsed, ...ex } = execution;
|
||||
try {
|
||||
await adminClient.authenticationManagement.updateExecution(
|
||||
{ flow: flow?.alias! },
|
||||
execution
|
||||
ex
|
||||
);
|
||||
refresh();
|
||||
addAlert(t("updateFlowSuccess"), AlertVariant.success);
|
||||
|
|
|
@ -2,11 +2,11 @@ import React, { useState } from "react";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Select, SelectOption, SelectVariant } from "@patternfly/react-core";
|
||||
|
||||
import type AuthenticationExecutionInfoRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticationExecutionInfoRepresentation";
|
||||
import type { ExpandableExecution } from "../execution-model";
|
||||
|
||||
type FlowRequirementDropdownProps = {
|
||||
flow: AuthenticationExecutionInfoRepresentation;
|
||||
onChange: (flow: AuthenticationExecutionInfoRepresentation) => void;
|
||||
flow: ExpandableExecution;
|
||||
onChange: (flow: ExpandableExecution) => void;
|
||||
};
|
||||
|
||||
export const FlowRequirementDropdown = ({
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { TrashIcon } from "@patternfly/react-icons";
|
||||
|
||||
import type AuthenticationExecutionInfoRepresentation from "@keycloak/keycloak-admin-client/lib/defs/authenticationExecutionInfoRepresentation";
|
||||
import type { AuthenticationProviderRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/authenticatorConfigRepresentation";
|
||||
import type { ExpandableExecution } from "../execution-model";
|
||||
import type { Flow } from "./modals/AddSubFlowModal";
|
||||
|
@ -30,7 +29,7 @@ type FlowRowProps = {
|
|||
builtIn: boolean;
|
||||
execution: ExpandableExecution;
|
||||
onRowClick: (execution: ExpandableExecution) => void;
|
||||
onRowChange: (execution: AuthenticationExecutionInfoRepresentation) => void;
|
||||
onRowChange: (execution: ExpandableExecution) => void;
|
||||
onAddExecution: (
|
||||
execution: ExpandableExecution,
|
||||
type: AuthenticationProviderRepresentation
|
||||
|
@ -115,6 +114,7 @@ export const FlowRow = ({
|
|||
<Tooltip content={t("common:delete")}>
|
||||
<Button
|
||||
variant="plain"
|
||||
data-testid={`${execution.displayName}-delete`}
|
||||
aria-label={t("common:delete")}
|
||||
onClick={() => onDelete(execution)}
|
||||
>
|
||||
|
|
Loading…
Reference in a new issue