Add Client Scopes Mappers tests (#4398)

This commit is contained in:
Aboullos 2023-02-16 10:56:50 +01:00 committed by GitHub
parent 9848ce6948
commit 1ca3f87df4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 298 additions and 27 deletions

View file

@ -11,11 +11,19 @@ import { keycloakBefore } from "../support/util/keycloak_hooks";
import RoleMappingTab from "../support/pages/admin-ui/manage/RoleMappingTab";
import ModalUtils from "../support/util/ModalUtils";
import adminClient from "../support/util/AdminClient";
import ClientScopeDetailsPage from "../support/pages/admin-ui/manage/client_scopes/client_scope_details/ClientScopeDetailsPage";
import CommonPage from "../support/pages/CommonPage";
import MappersTab from "../support/pages/admin-ui/manage/client_scopes/client_scope_details/tabs/MappersTab";
import MapperDetailsPage, {
ClaimJsonType,
} from "../support/pages/admin-ui/manage/client_scopes/client_scope_details/tabs/mappers/MapperDetailsPage";
let itemId = "client_scope_crud";
const loginPage = new LoginPage();
const masthead = new Masthead();
const sidebarPage = new SidebarPage();
const commonPage = new CommonPage();
const listingPage = new ListingPage();
const createClientScopePage = new CreateClientScopePage();
const modalUtils = new ModalUtils();
@ -163,7 +171,6 @@ describe("Client Scopes test", () => {
listingPage
.searchItem(clientScopeName, false)
.clickRowSelectItem(itemName, $assignedType);
// sidebarPage.waitForPageLoad(); //not working
cy.wait(2000);
listingPage.searchItem(itemName, false).itemExist($assignedType);
});
@ -199,7 +206,6 @@ describe("Client Scopes test", () => {
sidebarPage.goToClientScopes();
});
//TODO: Partially blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should delete item from item bar", () => {
listingPage
.checkInSearchBarChangeTypeToButtonIsDisabled()
@ -211,10 +217,9 @@ describe("Client Scopes test", () => {
masthead.checkNotificationMessage(
notificationMessageDeletionConfirmation
);
//listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
});
//TODO: Partially blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should delete selected item from search bar", () => {
listingPage
.checkInSearchBarChangeTypeToButtonIsDisabled()
@ -227,10 +232,9 @@ describe("Client Scopes test", () => {
masthead.checkNotificationMessage(
notificationMessageDeletionConfirmation
);
//listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
});
//TODO: Partially blocked by https://github.com/keycloak/keycloak-admin-ui/issues/1854
it("should delete multiple selected items from search bar", () => {
listingPage
.checkInSearchBarChangeTypeToButtonIsDisabled()
@ -245,7 +249,7 @@ describe("Client Scopes test", () => {
masthead.checkNotificationMessage(
notificationMessageDeletionConfirmation
);
//listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
listingPage.checkInSearchBarChangeTypeToButtonIsDisabled();
});
});
@ -262,7 +266,6 @@ describe("Client Scopes test", () => {
createClientScopePage.fillClientScopeData("address").save();
// The error should inform about duplicated name/id
masthead.checkNotificationMessage(
"Could not create client scope: 'Client Scope address already exists'"
);
@ -316,10 +319,17 @@ describe("Client Scopes test", () => {
});
});
describe("Scope test", () => {
describe("Scope tab test", () => {
const scopeTab = new RoleMappingTab("client-scope");
const scopeName = "address";
it.skip("Assign role", () => {
beforeEach(() => {
loginPage.logIn();
keycloakBefore();
sidebarPage.goToClientScopes();
});
it("Assign and unassign role", () => {
const role = "admin";
listingPage.searchItem(scopeName, false).goToItemDetails(scopeName);
scopeTab.goToScopeTab().assignRole().selectRow(role).assign();
@ -330,4 +340,68 @@ describe("Client Scopes test", () => {
scopeTab.checkRoles([]);
});
});
describe("Mappers tab test", () => {
const clientScopeDetailsPage = new ClientScopeDetailsPage();
const mappersTab = new MappersTab();
const mapperDetailsTab = new MapperDetailsPage();
const scopeName = "address";
beforeEach(() => {
loginPage.logIn();
keycloakBefore();
sidebarPage.goToClientScopes();
});
it("CRUD mappers", () => {
const predefinedMapperName = "Predefined Mapper test";
const predefinedMapper = "Allowed Web Origins";
const mappers1 = ["birthdate"];
const mappers2 = ["email verified", "email", "family name"];
listingPage.searchItem(scopeName, false).goToItemDetails(scopeName);
clientScopeDetailsPage
.goToMappersTab()
.addPredefinedMappers(mappers1)
.addPredefinedMappers(mappers2);
listingPage.searchItem(mappers1[0], false).goToItemDetails(mappers1[0]);
mapperDetailsTab
.fillUserAttribute(mappers1[0] + "1")
.fillTokenClaimName(mappers1[0] + "2")
.changeClaimJsonType(ClaimJsonType.Long);
commonPage.formUtils().save();
commonPage
.masthead()
.checkNotificationMessage("Mapping successfully updated");
sidebarPage.goToClientScopes();
listingPage.searchItem(scopeName, false).goToItemDetails(scopeName);
clientScopeDetailsPage.goToMappersTab();
listingPage.searchItem(mappers1[0], false).goToItemDetails(mappers1[0]);
mapperDetailsTab
.checkUserAttribute(mappers1[0] + "1")
.checkTokenClaimName(mappers1[0] + "2")
.checkClaimJsonType(ClaimJsonType.Long);
commonPage.formUtils().cancel();
mappersTab
.removeMappers(mappers1.concat(mappers2))
.addMappersByConfiguration(predefinedMapper, predefinedMapperName);
sidebarPage.goToClientScopes();
listingPage.searchItem(scopeName, false).goToItemDetails(scopeName);
clientScopeDetailsPage.goToMappersTab();
commonPage.tableUtils().checkRowItemExists(predefinedMapperName, true);
mappersTab.removeMappers([predefinedMapperName]);
});
});
});

View file

@ -4,6 +4,7 @@ export default class TablePage extends CommonElements {
private tableRowItem: string;
private tableRowItemChckBx: string;
private tableHeaderRowItem: string;
private tableInModal: boolean;
static tableSelector = "table[aria-label]";
constructor(parentElement?: string) {
@ -17,10 +18,17 @@ export default class TablePage extends CommonElements {
this.tableHeaderRowItem =
this.parentSelector + "thead tr[data-ouia-component-type]";
this.tableRowItemChckBx = ".pf-c-table__check";
this.tableInModal = false;
}
setTableInModal(value: boolean) {
this.tableInModal = value;
}
selectRowItemCheckbox(itemName: string) {
cy.get(this.tableRowItem)
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.contains(itemName)
.parentsUntil("tbody")
.find(this.tableRowItemChckBx)
@ -29,12 +37,18 @@ export default class TablePage extends CommonElements {
}
clickRowItemLink(itemName: string) {
cy.get(this.tableRowItem).contains(itemName).click();
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.contains(itemName)
.click();
return this;
}
selectRowItemAction(itemName: string, actionItemName: string) {
cy.get(this.tableRowItem)
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.contains(itemName)
.parentsUntil("tbody")
.find(".pf-c-dropdown__toggle")
@ -44,14 +58,26 @@ export default class TablePage extends CommonElements {
}
typeValueToRowItem(row: number, column: number, value: string) {
cy.get(this.tableRowItem + ":nth-child(" + row + ")")
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") +
this.tableRowItem +
":nth-child(" +
row +
")"
)
.find("td:nth-child(" + column + ")")
.type(value);
return this;
}
clickRowItemByIndex(row: number, column: number, appendChildren?: string) {
cy.get(this.tableRowItem + ":nth-child(" + row + ")")
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") +
this.tableRowItem +
":nth-child(" +
row +
")"
)
.find("td:nth-child(" + column + ") " + appendChildren)
.click();
return this;
@ -62,7 +88,9 @@ export default class TablePage extends CommonElements {
column: number,
appendChildren?: string
) {
cy.get(this.tableRowItem)
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.find("td:nth-child(" + column + ") " + appendChildren)
.contains(itemName)
.click();
@ -70,31 +98,46 @@ export default class TablePage extends CommonElements {
}
clickHeaderItem(column: number, appendChildren?: string) {
cy.get(this.tableHeaderRowItem)
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") +
this.tableHeaderRowItem
)
.find("td:nth-child(" + column + ") " + appendChildren)
.click();
return this;
}
checkRowItemsEqualTo(amount: number) {
cy.get(this.tableRowItem).its("length").should("be.eq", amount);
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.its("length")
.should("be.eq", amount);
return this;
}
checkRowItemsGreaterThan(amount: number) {
cy.get(this.tableRowItem).its("length").should("be.gt", amount);
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.its("length")
.should("be.gt", amount);
return this;
}
checkRowItemExists(itemName: string, exist = true) {
cy.get(this.tableRowItem)
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.contains(itemName)
.should((!exist ? "not." : "") + "exist");
return this;
}
checkRowItemValueByItemName(itemName: string, column: number, value: string) {
cy.get(this.tableRowItem)
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") + this.tableRowItem
)
.contains(itemName)
.parentsUntil("tbody")
.find("td:nth-child(" + column + ")")
@ -108,7 +151,13 @@ export default class TablePage extends CommonElements {
value: string,
appendChildren?: string
) {
cy.get(this.tableRowItem + ":nth-child(" + row + ")")
cy.get(
(this.tableInModal ? ".pf-c-modal-box.pf-m-md " : "") +
this.tableRowItem +
":nth-child(" +
row +
")"
)
.find("td:nth-child(" + column + ") " + appendChildren)
.should("have.text", value)
.should("have.value", value);

View file

@ -1,7 +1,7 @@
const expect = chai.expect;
export default class RoleMappingTab {
private type = "client";
private tab = "serviceAccountTab";
private serviceAccountTab = "serviceAccountTab";
private scopeTab = "scopeTab";
private assignEmptyRoleBtn = (type: string) =>
`no-roles-for-this-${type}-empty-action`;
@ -19,7 +19,7 @@ export default class RoleMappingTab {
}
goToServiceAccountTab() {
cy.findByTestId(this.tab).click();
cy.findByTestId(this.serviceAccountTab).click();
return this;
}

View file

@ -1,3 +0,0 @@
import CommonPage from "../../../CommonPage";
export default class ClientScopesPage extends CommonPage {}

View file

@ -0,0 +1,31 @@
import CommonPage from "../../../../CommonPage";
import SettingsTab from "./tabs/SettingsTab";
import MappersTab from "./tabs/MappersTab";
import ScopeTab from "./tabs/ScopeTab";
export enum ClientScopeDetailsTab {
SettingsTab = "Settings",
MappersTab = "Mappers",
Scope = "Scope",
}
export default class ClientScopeDetailsPage extends CommonPage {
private settingsTab = new SettingsTab();
private scopesTab = new ScopeTab();
private mappersTab = new MappersTab();
goToSettingsTab() {
this.tabUtils().clickTab(ClientScopeDetailsTab.SettingsTab);
return this.settingsTab;
}
goToMappersTab() {
this.tabUtils().clickTab(ClientScopeDetailsTab.MappersTab);
return this.mappersTab;
}
goToScopesTab() {
this.tabUtils().clickTab(ClientScopeDetailsTab.Scope);
return this.scopesTab;
}
}

View file

@ -0,0 +1,62 @@
import CommonPage from "../../../../../CommonPage";
export default class MappersTab extends CommonPage {
private addMapperBtn = "#mapperAction";
private fromPredefinedMappersBtn =
'ul[aria-labelledby="mapperAction"] > li:nth-child(1) a';
private byConfigurationBtn =
'ul[aria-labelledby="mapperAction"] > li:nth-child(2) a';
private mapperConfigurationList =
'ul[aria-label="Add predefined mappers"] > li:not([id=header])';
private mapperNameInput = "#name";
addPredefinedMappers(mappersNames: string[]) {
cy.get(this.addMapperBtn).click();
cy.get(this.fromPredefinedMappersBtn).click();
this.tableUtils().setTableInModal(true);
for (const mapperName of mappersNames) {
this.tableUtils().selectRowItemCheckbox(mapperName);
}
this.tableUtils().setTableInModal(false);
this.modalUtils().confirmModal();
this.masthead().checkNotificationMessage("Mapping successfully created");
this.sidebar().waitForPageLoad();
cy.contains(mappersNames[0]).should("exist");
for (const mapperName of mappersNames) {
this.tableUtils().checkRowItemExists(mapperName, true);
}
return this;
}
addMappersByConfiguration(predefinedMapperName: string, mapperName: string) {
cy.get(this.addMapperBtn).click();
cy.get(this.byConfigurationBtn).click();
cy.get(this.mapperConfigurationList).contains(predefinedMapperName).click();
cy.get(this.mapperNameInput).type(mapperName);
this.formUtils().save();
this.masthead().checkNotificationMessage("Mapping successfully created");
return this;
}
removeMappers(mappersNames: string[]) {
for (const mapperName of mappersNames) {
this.tableUtils().checkRowItemExists(mapperName);
this.tableUtils().selectRowItemAction(mapperName, "Delete");
this.sidebar().waitForPageLoad();
this.masthead().checkNotificationMessage("Mapping successfully deleted");
this.sidebar().waitForPageLoad();
this.tableUtils().checkRowItemExists(mapperName, false);
}
return this;
}
}

View file

@ -0,0 +1,3 @@
import CommonPage from "../../../../../CommonPage";
export default class ScopeTab extends CommonPage {}

View file

@ -0,0 +1,3 @@
import PageObject from "../../../../components/PageObject";
export default class SettingsTab extends PageObject {}

View file

@ -0,0 +1,52 @@
import CommonPage from "../../../../../../CommonPage";
export enum ClaimJsonType {
String = "String",
Long = "long",
Int = "int",
Boolean = "boolean",
Json = "JSON",
}
export default class MapperDetailsPage extends CommonPage {
private userAttributeInput = '[id="user.attribute"]';
private tokenClaimNameInput = '[id="claim.name"]';
private claimJsonType = '[id="jsonType.label"]';
fillUserAttribute(userAttribute: string) {
cy.get(this.userAttributeInput).clear().type(userAttribute);
return this;
}
checkUserAttribute(userAttribute: string) {
cy.get(this.userAttributeInput).should("have.value", userAttribute);
return this;
}
fillTokenClaimName(name: string) {
cy.get(this.tokenClaimNameInput).clear().type(name);
return this;
}
checkTokenClaimName(name: string) {
cy.get(this.tokenClaimNameInput).should("have.value", name);
return this;
}
changeClaimJsonType(type: string) {
cy.get(this.claimJsonType).click();
cy.get(this.claimJsonType).parent().contains(type).click();
return this;
}
checkClaimJsonType(type: string) {
cy.get(this.claimJsonType).should("contain", type);
return this;
}
}