using smarter wait to fix group tests (#604)

* using smarter wait

instead of static waiting wait for the memeber query to finish

* revert

* query less by creating navigation on click

* only search in the displayed table

* fixed test
This commit is contained in:
Erik Jan de Wit 2021-05-18 14:25:46 +02:00 committed by GitHub
parent 2c23807742
commit a9a34102bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 66 deletions

View file

@ -22,8 +22,17 @@ describe("Group test", () => {
let groupName = "group";
const clickGroup = (itemName: string) => {
const membersUrl = `/auth/admin/realms/master/groups/*/members`;
cy.intercept(membersUrl).as("groupFetch");
cy.get("table").contains(itemName).click();
cy.wait(["@groupFetch"]);
return this;
};
describe("Group creation", () => {
beforeEach(function () {
beforeEach(() => {
keycloakBefore();
loginPage.logIn();
sidebarPage.goToGroups();
@ -52,7 +61,7 @@ describe("Group test", () => {
.open("empty-primary-action")
.fillGroupForm(groupName)
.clickCreate();
listingPage.goToItemDetails(groupName);
clickGroup(groupName);
viewHeaderPage.clickAction("renameGroupAction");
const newName = "Renamed group";
@ -62,6 +71,7 @@ describe("Group test", () => {
sidebarPage.goToGroups();
listingPage.searchItem(newName, false).itemExist(newName);
listingPage.deleteItem(newName);
masthead.checkNotificationMessage("Group deleted");
});
it("Should move group", () => {
@ -78,12 +88,12 @@ describe("Group test", () => {
moveGroupModal.clickMove();
masthead.checkNotificationMessage("Group moved");
listingPage.itemExist(groupName, false).goToItemDetails(targetGroupName);
cy.wait(2000);
listingPage.itemExist(groupName, false);
clickGroup(targetGroupName);
listingPage.itemExist(groupName);
cy.wait(1000);
sidebarPage.goToGroups();
listingPage.deleteItem(targetGroupName);
masthead.checkNotificationMessage("Group deleted");
});
it("Should move group to root", async () => {
@ -141,7 +151,7 @@ describe("Group test", () => {
});
it("Should display all the subgroups", () => {
listingPage.goToItemDetails(groups[0]);
clickGroup(groups[0]);
detailPage.checkListSubGroup([groups[1]]);
const added = "addedGroup";
@ -151,7 +161,7 @@ describe("Group test", () => {
});
it("Should display members", () => {
listingPage.goToItemDetails(groups[0]);
clickGroup(groups[0]);
detailPage.clickMembersTab().checkListMembers(["user0", "user3"]);
detailPage
.clickIncludeSubGroups()
@ -159,7 +169,7 @@ describe("Group test", () => {
});
it("Should add members", () => {
listingPage.goToItemDetails(groups[0]);
clickGroup(groups[0]);
detailPage
.clickMembersTab()
.clickAddMembers()
@ -171,7 +181,7 @@ describe("Group test", () => {
});
it("Attributes CRUD test", () => {
listingPage.goToItemDetails(groups[0]);
clickGroup(groups[0]);
detailPage
.clickAttributesTab()
.fillAttribute("key", "value")

View file

@ -229,14 +229,12 @@ export function KeycloakDataTable<T>({
return node.map(getNodeText).join("");
}
if (typeof node === "object" && node) {
if ((node as TitleCell).title) {
return getNodeText(
isValidElement((node as TitleCell).title)
? (node as TitleCell).title.props.children
: (node as JSX.Element).props.children
);
}
}
return "";
};

View file

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useState } from "react";
import { Link, useHistory, useLocation } from "react-router-dom";
import { useTranslation } from "react-i18next";
import _ from "lodash";
@ -14,7 +14,6 @@ import { UsersIcon } from "@patternfly/react-icons";
import GroupRepresentation from "keycloak-admin/lib/defs/groupRepresentation";
import { useAdminClient } from "../context/auth/AdminClient";
import { useSubGroups } from "./SubGroupsContext";
import { useAlerts } from "../components/alert/Alerts";
import { useRealm } from "../context/realm-context/RealmContext";
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
@ -22,6 +21,7 @@ import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
import { GroupsModal } from "./GroupsModal";
import { getLastId } from "./groupIdUtils";
import { MoveGroupDialog } from "./MoveGroupDialog";
import { useSubGroups } from "./SubGroupsContext";
type GroupTableData = GroupRepresentation & {
membersLength?: number;
@ -38,7 +38,7 @@ export const GroupTable = () => {
const [selectedRows, setSelectedRows] = useState<GroupRepresentation[]>([]);
const [move, setMove] = useState<GroupTableData>();
const { subGroups } = useSubGroups();
const { subGroups, setSubGroups } = useSubGroups();
const [key, setKey] = useState(0);
const refresh = () => setKey(new Date().getTime());
@ -47,30 +47,15 @@ export const GroupTable = () => {
const location = useLocation();
const id = getLastId(location.pathname);
useEffect(() => {
refresh();
}, [subGroups]);
const getMembers = async (id: string) => {
const response = await adminClient.groups.listMembers({ id });
return response ? response.length : 0;
};
const loader = async (first?: number, max?: number, search?: string) => {
const params: { [name: string]: string | number } = {
first: first!,
max: max!,
};
const searchParam = search || "";
if (searchParam) {
params.search = searchParam;
}
const loader = async () => {
const groupsData = id
? (await adminClient.groups.findOne({ id, ...params })).subGroups
: await adminClient.groups.find(params);
? (await adminClient.groups.findOne({ id })).subGroups
: await adminClient.groups.find();
if (groupsData) {
const memberPromises = groupsData.map((group) => getMembers(group.id!));
@ -111,7 +96,14 @@ export const GroupTable = () => {
const GroupNameCell = (group: GroupTableData) => (
<>
<Link key={group.id} to={`${location.pathname}/${group.id}`}>
<Link
key={group.id}
to={`${location.pathname}/${group.id}`}
onClick={() => {
delete group.membersLength;
setSubGroups([...subGroups, group]);
}}
>
{group.name}
</Link>
</>
@ -131,8 +123,7 @@ export const GroupTable = () => {
return (
<>
<KeycloakDataTable
key={key}
isPaginated
key={`${id}${key}`}
onSelect={(rows) => setSelectedRows([...rows])}
canSelectAll={false}
loader={loader}

View file

@ -60,8 +60,8 @@ export const GroupsSection = () => {
asyncStateFetch(
async () => {
const ids = getId(location.pathname);
const isNavigationStateInValid =
ids && ids.length !== subGroups.length + 1;
const isNavigationStateInValid = ids && ids.length > subGroups.length;
if (isNavigationStateInValid) {
const groups: GroupRepresentation[] = [];
for (const i of ids!) {
@ -69,20 +69,12 @@ export const GroupsSection = () => {
if (group) groups.push(group);
}
return groups;
} else {
if (id) {
const group = await adminClient.groups.findOne({ id: id });
if (group) {
return [...subGroups, group];
} else {
return subGroups;
}
} else {
return subGroups;
}
}
return [];
},
(groups: GroupRepresentation[]) => {
if (groups.length) setSubGroups(groups);
},
(groups: GroupRepresentation[]) => setSubGroups(groups),
errorHandler
),
[id]

View file

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React, { useState } from "react";
import { useLocation } from "react-router-dom";
import { useTranslation } from "react-i18next";
import _ from "lodash";
@ -35,7 +35,7 @@ export const Members = () => {
const location = useLocation();
const id = getLastId(location.pathname);
const [includeSubGroup, setIncludeSubGroup] = useState(false);
const { currentGroup, subGroups } = useSubGroups();
const { currentGroup } = useSubGroups();
const [addMembers, setAddMembers] = useState(false);
const [isKebabOpen, setIsKebabOpen] = useState(false);
const [selectedRows, setSelectedRows] = useState<UserRepresentation[]>([]);
@ -43,10 +43,6 @@ export const Members = () => {
const [key, setKey] = useState(0);
const refresh = () => setKey(new Date().getTime());
useEffect(() => {
refresh();
}, [id, subGroups, includeSubGroup]);
const getMembership = async (id: string) =>
await adminClient.users.listGroups({ id: id! });
@ -107,7 +103,7 @@ export const Members = () => {
/>
)}
<KeycloakDataTable
key={key}
key={`${id}${key}${includeSubGroup}`}
loader={loader}
ariaLabelKey="groups:members"
isPaginated

View file

@ -25,10 +25,7 @@ export const SubGroups = ({ children }: { children: ReactNode }) => {
const clear = () => setSubGroups([]);
const remove = (group: GroupRepresentation) =>
setSubGroups(
subGroups.slice(
0,
subGroups.findIndex((g) => g.id === group.id)
)
subGroups.slice(0, subGroups.findIndex((g) => g.id === group.id) + 1)
);
const currentGroup = () => subGroups[subGroups.length - 1];
return (