diff --git a/cypress/integration/masthead_test.spec.ts b/cypress/integration/masthead_test.spec.ts index e5002d0e8f..95922c3070 100644 --- a/cypress/integration/masthead_test.spec.ts +++ b/cypress/integration/masthead_test.spec.ts @@ -2,13 +2,19 @@ import ListingPage from "../support/pages/admin_console/ListingPage"; import LoginPage from "../support/pages/LoginPage"; import SidebarPage from "../support/pages/admin_console/SidebarPage"; import Masthead from "../support/pages/admin_console/Masthead"; -import { keycloakBefore } from "../support/util/keycloak_hooks"; +import { + keycloakBefore, + keycloakBeforeEach, +} from "../support/util/keycloak_hooks"; const loginPage = new LoginPage(); const masthead = new Masthead(); +const listingPage = new ListingPage(); +const sidebarPage = new SidebarPage(); const logOutTest = () => { it("logs out", () => { + sidebarPage.waitForPageLoad(); masthead.signOut(); loginPage.isLogInPage(); }); @@ -16,6 +22,7 @@ const logOutTest = () => { const goToAcctMgtTest = () => { it("opens manage account and returns to admin console", () => { + sidebarPage.waitForPageLoad(); masthead.accountManagement(); cy.contains("Welcome to Keycloak Account Management"); cy.get("#landingReferrerLink").click({ force: true }); @@ -24,17 +31,18 @@ const goToAcctMgtTest = () => { }; describe("Masthead tests in desktop mode", () => { - beforeEach(() => { + before(() => { keycloakBefore(); loginPage.logIn(); }); + beforeEach(() => { + keycloakBeforeEach(); + }); + goToAcctMgtTest(); it("disables header help and form field help", () => { - const sidebarPage = new SidebarPage(); - const listingPage = new ListingPage(); - sidebarPage.goToClientScopes(); listingPage.goToItemDetails("address"); @@ -51,12 +59,16 @@ describe("Masthead tests in desktop mode", () => { }); describe("Masthead tests with kebab menu", () => { - beforeEach(() => { + before(() => { keycloakBefore(); loginPage.logIn(); masthead.setMobileMode(true); }); + beforeEach(() => { + keycloakBeforeEach(); + }); + it("shows kabab and hides regular menu", () => { masthead.checkKebabShown(); }); diff --git a/cypress/integration/partial_import_test.spec.ts b/cypress/integration/partial_import_test.spec.ts index dcab99a324..81532b4925 100644 --- a/cypress/integration/partial_import_test.spec.ts +++ b/cypress/integration/partial_import_test.spec.ts @@ -3,7 +3,10 @@ import SidebarPage from "../support/pages/admin_console/SidebarPage"; import LoginPage from "../support/pages/LoginPage"; import PartialImportModal from "../support/pages/admin_console/configure/realm_settings/PartialImportModal"; import RealmSettings from "../support/pages/admin_console/configure/realm_settings/RealmSettings"; -import { keycloakBefore } from "../support/util/keycloak_hooks"; +import { + keycloakBefore, + keycloakBeforeEach, +} from "../support/util/keycloak_hooks"; import AdminClient from "../support/util/AdminClient"; describe("Partial import test", () => { @@ -14,11 +17,13 @@ describe("Partial import test", () => { const modal = new PartialImportModal(); const realmSettings = new RealmSettings(); - beforeEach(() => { + before(() => { keycloakBefore(); loginPage.logIn(); - sidebarPage.waitForPageLoad(); + }); + beforeEach(() => { + keycloakBeforeEach(); // doing this from the UI has the added bonus of putting you in the test realm sidebarPage.goToCreateRealm(); createRealmPage.fillRealmName(TEST_REALM).createRealm(); @@ -43,6 +48,7 @@ describe("Partial import test", () => { modal.open(); cy.get(".pf-c-code-editor__code textarea").type("{}"); modal.importButton().should("be.disabled"); + modal.cancelButton().click(); }); it("Displays user options after multi-realm import", () => { @@ -81,6 +87,7 @@ describe("Partial import test", () => { cy.contains("2 records added"); cy.contains("customer-portal"); cy.contains("customer-portal2"); + modal.closeButton().click(); }); it("Displays user options after realmless import and does the import", () => { diff --git a/cypress/support/pages/admin_console/configure/realm_settings/PartialImportModal.ts b/cypress/support/pages/admin_console/configure/realm_settings/PartialImportModal.ts index 0057d56673..6e75c35062 100644 --- a/cypress/support/pages/admin_console/configure/realm_settings/PartialImportModal.ts +++ b/cypress/support/pages/admin_console/configure/realm_settings/PartialImportModal.ts @@ -30,6 +30,10 @@ export default class GroupModal { return cy.findByTestId("cancel-button"); } + closeButton() { + return cy.findByTestId("close-button"); + } + usersCheckbox() { return cy.findByTestId("users-checkbox"); } diff --git a/src/context/RealmsContext.tsx b/src/context/RealmsContext.tsx index ee9f11f781..15503a87b3 100644 --- a/src/context/RealmsContext.tsx +++ b/src/context/RealmsContext.tsx @@ -7,6 +7,8 @@ import React, { useMemo, useState, } from "react"; +import axios from "axios"; + import { RecentUsed } from "../components/realm-selector/recent-used"; import useRequiredContext from "../utils/useRequiredContext"; import { useAdminClient, useFetch } from "./auth/AdminClient"; @@ -33,7 +35,21 @@ export const RealmsProvider: FunctionComponent = ({ children }) => { } useFetch( - () => adminClient.realms.find({ briefRepresentation: true }), + async () => { + try { + return await adminClient.realms.find({ briefRepresentation: true }); + } catch (error) { + if ( + axios.isAxiosError(error) && + error.response && + error.response.status < 500 + ) { + return []; + } + + throw error; + } + }, (realms) => updateRealms(realms), [] ); diff --git a/src/context/server-info/ServerInfoProvider.tsx b/src/context/server-info/ServerInfoProvider.tsx index 420de5599d..8bf38e5ef7 100644 --- a/src/context/server-info/ServerInfoProvider.tsx +++ b/src/context/server-info/ServerInfoProvider.tsx @@ -1,9 +1,9 @@ +import React, { createContext, FunctionComponent, useState } from "react"; + import type { ServerInfoRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; -import React, { createContext, FunctionComponent } from "react"; -import { DataLoader } from "../../components/data-loader/DataLoader"; import { sortProviders } from "../../util"; import useRequiredContext from "../../utils/useRequiredContext"; -import { useAdminClient } from "../auth/AdminClient"; +import { useAdminClient, useFetch } from "../auth/AdminClient"; export const ServerInfoContext = createContext< ServerInfoRepresentation | undefined @@ -17,16 +17,23 @@ export const useLoginProviders = () => { export const ServerInfoProvider: FunctionComponent = ({ children }) => { const adminClient = useAdminClient(); - const loader = async () => { - return await adminClient.serverInfo.find(); - }; + const [serverInfo, setServerInfo] = useState({}); + + useFetch( + async () => { + try { + return await adminClient.serverInfo.find(); + } catch (error) { + return {}; + } + }, + setServerInfo, + [] + ); + return ( - - {(serverInfo) => ( - - {children} - - )} - + + {children} + ); }; diff --git a/src/dashboard/Dashboard.tsx b/src/dashboard/Dashboard.tsx index cec5794525..9a4c0b0a5f 100644 --- a/src/dashboard/Dashboard.tsx +++ b/src/dashboard/Dashboard.tsx @@ -26,12 +26,13 @@ import { xor } from "lodash-es"; import { useRealm } from "../context/realm-context/RealmContext"; import { useServerInfo } from "../context/server-info/ServerInfoProvider"; - -import "./dashboard.css"; import { toUpperCase } from "../util"; import { HelpItem } from "../components/help-enabler/HelpItem"; import environment from "../environment"; +import "./dashboard.css"; +import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner"; + const EmptyDashboard = () => { const { t } = useTranslation("dashboard"); const { realm } = useRealm(); @@ -74,6 +75,10 @@ const Dashboard = () => { return serverInfo.profileInfo?.previewFeatures?.includes(feature); }; + if (Object.keys(serverInfo).length === 0) { + return ; + } + return ( <>