Skip to content

fix: gubbins tests #376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/gubbins-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -330,3 +330,10 @@ jobs:
browser: chrome
config: baseUrl=${{ env.DIRACX_URL }}
project: /tmp/gubbins-web

- name: Upload Cypress screenshots
if: failure()
uses: actions/upload-artifact@v4
with:
name: cypress-screenshots
path: /tmp/gubbins-web/cypress/screenshots
2 changes: 1 addition & 1 deletion docs/developer/create_application.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The applicatins created here will be available for DiracX-Web and for all the ex

### Declare the application

In the file `packages/diracx-web-components/src/components/ApplicationList.ts` you can extend the `applicationList` with your new app.
In the file `packages/diracx-web-components/src/components/applicationList.ts` you can extend the `applicationList` with your new app.

You must provide:
- A clear and explicit name
Expand Down
15 changes: 15 additions & 0 deletions packages/diracx-web-components/src/components/defaultDashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { DashboardGroup } from "../types/DashboardGroup";

export const defaultDashboard: DashboardGroup[] = [
{
title: "My dashboard",
extended: true,
items: [
{
title: "My Jobs",
type: "Job Monitor",
id: "JobMonitor0",
},
],
},
];
2 changes: 1 addition & 1 deletion packages/diracx-web-components/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Application list
export { applicationList } from "./ApplicationList";
export { applicationList } from "./applicationList";

// Dashboard Layout
export * from "./DashboardLayout";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"use client";

import React, { createContext, useEffect, useState } from "react";
import { applicationList } from "../components/ApplicationList";
import { applicationList } from "../components/applicationList";
import { defaultDashboard } from "../components/defaultDashboard";
import { DashboardGroup } from "../types/DashboardGroup";
import ApplicationMetadata from "../types/ApplicationMetadata";

Expand Down Expand Up @@ -33,7 +34,7 @@ interface ApplicationsProviderProps {
export const ApplicationsProvider = ({
children,
appList = applicationList,
defaultUserDashboard,
defaultUserDashboard = defaultDashboard,
}: ApplicationsProviderProps) => {
const loadedDashboard = sessionStorage.getItem("savedDashboard");
const parsedDashboard: DashboardGroup[] = loadedDashboard
Expand All @@ -51,21 +52,7 @@ export const ApplicationsProvider = ({
useEffect(() => {
if (userDashboard.length !== 0) return;

setUserDashboard(
defaultUserDashboard || [
{
title: "My dashboard",
extended: true,
items: [
{
title: "My Jobs",
type: "Job Monitor",
id: "JobMonitor0",
},
],
},
],
);
setUserDashboard(defaultUserDashboard);
}, [appList, defaultUserDashboard]);

// Save the dashboard in session storage
Expand Down
16 changes: 14 additions & 2 deletions packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
"use client";

import type { ApplicationMetadata, DashboardGroup } from "../types";

import { OIDCSecure } from "../components";
import {
OIDCConfigurationProvider,
ThemeProvider,
Expand All @@ -12,13 +15,17 @@ interface DiracXWebProvidersProps {
getPath: () => string;
setPath: (path: string) => void;
getSearchParams: () => URLSearchParams;
appList?: ApplicationMetadata[];
defaultUserDashboard?: DashboardGroup[];
}

export function DiracXWebProviders({
children,
getPath,
setPath,
getSearchParams,
appList,
defaultUserDashboard,
}: DiracXWebProvidersProps) {
return (
<OIDCConfigurationProvider>
Expand All @@ -27,8 +34,13 @@ export function DiracXWebProviders({
setPath={setPath}
getSearchParams={getSearchParams}
>
<ApplicationsProvider>
<ThemeProvider>{children}</ThemeProvider>
<ApplicationsProvider
appList={appList}
defaultUserDashboard={defaultUserDashboard}
>
<ThemeProvider>
<OIDCSecure>{children}</OIDCSecure>
</ThemeProvider>
</ApplicationsProvider>
</NavigationProvider>
</OIDCConfigurationProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import { Box } from "@mui/material";
import { ApplicationsContext } from "../src/contexts/ApplicationsProvider";
import { NavigationProvider } from "../src/contexts/NavigationProvider";
import { applicationList } from "../src/components/ApplicationList";
import { applicationList } from "../src/components/applicationList";
import { DashboardGroup } from "../src/types/DashboardGroup";
import Dashboard from "../src/components/DashboardLayout/Dashboard";
import { ThemeProvider } from "../src/contexts/ThemeProvider";
Expand Down
35 changes: 15 additions & 20 deletions packages/diracx-web/src/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
import React from "react";
import { Box } from "@mui/material";
import { DiracXWebProviders } from "@dirac-grid/diracx-web-components/contexts";
import {
OIDCSecure,
Dashboard,
} from "@dirac-grid/diracx-web-components/components";
import { Dashboard } from "@dirac-grid/diracx-web-components/components";
import { usePathname, useRouter, useSearchParams } from "next/navigation";

export default function DashboardLayout({
Expand All @@ -25,22 +22,20 @@ export default function DashboardLayout({
}}
getSearchParams={() => searchParams}
>
<OIDCSecure>
<Dashboard>
<Box
sx={{
ml: "1%",
mr: "1%",
display: "flex",
flexDirection: "column",
flexGrow: 1,
overflow: "hidden",
}}
>
{children}
</Box>
</Dashboard>
</OIDCSecure>
<Dashboard>
<Box
sx={{
ml: "1%",
mr: "1%",
display: "flex",
flexDirection: "column",
flexGrow: 1,
overflow: "hidden",
}}
>
{children}
</Box>
</Dashboard>
</DiracXWebProviders>
</section>
);
Expand Down
55 changes: 21 additions & 34 deletions packages/extensions/src/app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
"use client";
import React from "react";
import { Box } from "@mui/material";
import {
OIDCSecure,
Dashboard,
} from "@dirac-grid/diracx-web-components/components";
import {
ApplicationsProvider,
DiracXWebProviders,
} from "@dirac-grid/diracx-web-components/contexts";
import { Dashboard } from "@dirac-grid/diracx-web-components/components";
import { DiracXWebProviders } from "@dirac-grid/diracx-web-components/contexts";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { applicationList } from "@/gubbins/ApplicationList";
import { applicationList } from "@/gubbins/applicationList";
import { defaultSections } from "@/gubbins/DefaultUserDashboard";

// Layout for the dashboard: setup the providers and the dashboard for the applications
Expand All @@ -32,32 +26,25 @@ export default function DashboardLayout({
getPath={() => pathname}
setPath={router.push}
getSearchParams={() => searchParams}
// You can optionally pass a list of applications and a default user dashboard
appList={applicationList}
defaultUserDashboard={defaultSections}
>
{/* ApplicationsProvider is the provider for the applications, you can give it customized application list or default user dashboard to override them.
No need to use it if you don't want to customize the applications */}
<ApplicationsProvider
appList={applicationList}
defaultUserDashboard={defaultSections}
>
{/* OIDCSecure is used to make sure the user is authenticated before accessing the dashboard */}
<OIDCSecure>
{/* Dashboard is the main layout for the applications, you can optionally give it a custom logo URL and a drawer width */}
<Dashboard logoURL={customLogoURL} drawerWidth={250}>
<Box
sx={{
ml: "1%",
mr: "1%",
display: "flex",
flexDirection: "column",
flexGrow: 1,
overflow: "hidden",
}}
>
{children}
</Box>
</Dashboard>
</OIDCSecure>
</ApplicationsProvider>
{/* Dashboard is the main layout for the applications, you can optionally give it a custom logo URL and a drawer width */}
<Dashboard logoURL={customLogoURL} drawerWidth={250}>
<Box
sx={{
ml: "1%",
mr: "1%",
display: "flex",
flexDirection: "column",
flexGrow: 1,
overflow: "hidden",
}}
>
{children}
</Box>
</Dashboard>
</DiracXWebProviders>
);
}
5 changes: 5 additions & 0 deletions packages/extensions/src/app/auth/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import React from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { DiracXWebProviders } from "@dirac-grid/diracx-web-components/contexts";
import { applicationList } from "@/gubbins/applicationList";
import { defaultSections } from "@/gubbins/DefaultUserDashboard";

// Layout for the authentication page: setup the navigation provider
export default function AuthLayout({
Expand All @@ -19,6 +21,9 @@ export default function AuthLayout({
getPath={() => pathname}
setPath={router.push}
getSearchParams={() => searchParams}
// You can optionally pass a list of applications and a default user dashboard
appList={applicationList}
defaultUserDashboard={defaultSections}
>
{children}
</DiracXWebProviders>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";
import React, { useMemo, useState } from "react";
import React, { useMemo, useState, useEffect, useCallback } from "react";
import { useOidcAccessToken } from "@axa-fr/react-oidc";
import {
fetcher,
Expand Down Expand Up @@ -34,7 +34,7 @@ export default function OwnerMonitor() {
});

// Fetch the list of owners
const fetchOwners = async () => {
const fetchOwners = useCallback(async () => {
try {
setIsLoading(true);
const response = await fetcher<string[]>([
Expand All @@ -53,7 +53,7 @@ export default function OwnerMonitor() {
} finally {
setIsLoading(false);
}
};
}, [accessToken]);

// Handle adding a new owner
const handleAddOwner = async () => {
Expand Down Expand Up @@ -91,6 +91,10 @@ export default function OwnerMonitor() {
onPaginationChange: setPagination,
});

useEffect(() => {
fetchOwners();
}, [fetchOwners]);

return (
<Box
sx={{
Expand Down
6 changes: 4 additions & 2 deletions packages/extensions/test/e2e/loginOut.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe("Login and Logout", () => {
// so we must tell it to visit our website with the `cy.visit()` command.
// Since we want to visit the same URL at the start of all our tests,
// we include it in our beforeEach function so that it runs before each test
cy.visit("/");
cy.visit("/auth");
});

it("login", () => {
Expand Down Expand Up @@ -43,7 +43,9 @@ describe("Login and Logout", () => {
// From now on the user is logged in
// The login buttton should not be present anymore
cy.get('[data-testid="button-login"]').should("not.exist");
cy.contains("Hello admin").should("exist");

cy.visit("/");
cy.contains("Owners").should("exist");

// Click on the user avatar
cy.get(".MuiAvatar-root").click();
Expand Down
16 changes: 10 additions & 6 deletions packages/extensions/test/e2e/ownerMonitor.cy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// <reference types="cypress" />

describe("Job Monitor", () => {
describe("Owner Monitor", () => {
beforeEach(() => {
cy.session("login", () => {
cy.visit("/");
cy.visit("/auth");
//login
cy.get('[data-testid="button-login"]').click();
cy.get("#login").type("[email protected]");
Expand All @@ -17,9 +17,14 @@ describe("Job Monitor", () => {
});

// Visit the page where the Job Monitor is rendered
cy.visit(
"/?appId=OwnerMonitor1&dashboard=%5B3Gubbins+Apps%27~extended%21true~items%21%5B-020.04~data%21%5B%5D%29%2C3Job2Job.Job4%29%5D%29%5D*Monitor-%28%27title%21%27.*1%27~type%21%270Owner2s%27~id%21%273-My+4+*%27%014320.-*_",
);
cy.window().then((win) => {
win.sessionStorage.setItem(
"savedDashboard",
'[{"title":"Group 2","extended":true,"items":[{"title":"Owner Monitor","id":"JOwner Monitor0","type":"Owner Monitor"},{"title":"Owner Monitor 2","id":"Owner Monitor 21","type":"Owner Monitor"}]}]',
);
});

cy.visit("/");
});

it("should render the drawer", () => {
Expand Down Expand Up @@ -47,7 +52,6 @@ describe("Job Monitor", () => {
});

/** Column interactions */

it("should hide/show columns", () => {
// Click on the visibility icon
cy.get('[data-testid="VisibilityIcon"] > path').click();
Expand Down