From f6dfa3f76a1d018b17a05294924024583f84b7ec Mon Sep 17 00:00:00 2001 From: theau Date: Fri, 27 Jun 2025 11:10:30 +0200 Subject: [PATCH 1/3] fix: fix the tests of gubbins --- .github/workflows/diracx-web-test.yml | 2 +- .github/workflows/gubbins-test.yml | 8 ++++---- packages/extensions/test/e2e/loginOut.cy.ts | 2 +- packages/extensions/test/e2e/ownerMonitor.cy.ts | 12 ++++++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/diracx-web-test.yml b/.github/workflows/diracx-web-test.yml index 0a58f5dc..fe2c82b0 100644 --- a/.github/workflows/diracx-web-test.yml +++ b/.github/workflows/diracx-web-test.yml @@ -25,7 +25,7 @@ jobs: - name: Clone source run: | cd .. - git clone https://github.com/DIRACGrid/diracx-charts.git + git clone https://github.com/aldbr/diracx-charts.git -b main_FIX_diracx-web-install-resources - name: Start demo run: | diff --git a/.github/workflows/gubbins-test.yml b/.github/workflows/gubbins-test.yml index cb15ad76..0cd2114c 100644 --- a/.github/workflows/gubbins-test.yml +++ b/.github/workflows/gubbins-test.yml @@ -53,7 +53,7 @@ jobs: # standalone setup. # prepare-gubbins-backend: runs-on: ubuntu-latest - if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} + if: github.event_name == 'push' #${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} defaults: run: # We need extglob for REFERENCE_BRANCH substitution @@ -152,7 +152,7 @@ jobs: prepare-gubbins-frontend-as-a-standalone: runs-on: ubuntu-latest - if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} + if: github.event_name == 'push' #${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} steps: - uses: actions/checkout@v4 @@ -246,14 +246,14 @@ jobs: run-demo: runs-on: ubuntu-latest needs: [prepare-gubbins-frontend-as-a-standalone, prepare-gubbins-backend] - if: github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' + if: github.event_name == 'push' #github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' steps: - uses: actions/checkout@v4 - name: Clone source run: | cd .. - git clone https://github.com/DIRACGrid/diracx-charts.git + git clone https://github.com/TheauW/diracx-charts.git -b twartel-fix-ci # ========================================================================# # WARNING: In your CI/CD pipeline, you should remove the following steps # diff --git a/packages/extensions/test/e2e/loginOut.cy.ts b/packages/extensions/test/e2e/loginOut.cy.ts index 899474bb..c3994eb6 100644 --- a/packages/extensions/test/e2e/loginOut.cy.ts +++ b/packages/extensions/test/e2e/loginOut.cy.ts @@ -43,7 +43,7 @@ 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.contains("Owners").should("exist"); // Click on the user avatar cy.get(".MuiAvatar-root").click(); diff --git a/packages/extensions/test/e2e/ownerMonitor.cy.ts b/packages/extensions/test/e2e/ownerMonitor.cy.ts index ff81c400..e4595a7e 100644 --- a/packages/extensions/test/e2e/ownerMonitor.cy.ts +++ b/packages/extensions/test/e2e/ownerMonitor.cy.ts @@ -3,7 +3,7 @@ describe("Job Monitor", () => { beforeEach(() => { cy.session("login", () => { - cy.visit("/"); + cy.visit("/auth"); //login cy.get('[data-testid="button-login"]').click(); cy.get("#login").type("admin@example.com"); @@ -17,12 +17,16 @@ 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"}]}]', + ); + }); }); it("should render the drawer", () => { + cy.wait(20000); cy.get("header").contains("Owner Monitor").should("be.visible"); }); From 818adc6e9e15127f6dd694f13db6334301731db5 Mon Sep 17 00:00:00 2001 From: theau Date: Mon, 30 Jun 2025 13:57:04 +0200 Subject: [PATCH 2/3] fix: remove the second definition of the application provider --- .github/workflows/diracx-web-test.yml | 2 +- .github/workflows/gubbins-test.yml | 15 +++-- docs/developer/create_application.md | 2 +- ...{ApplicationList.ts => applicationList.ts} | 0 .../src/components/defaultDashboard.ts | 15 +++++ .../src/components/index.ts | 2 +- .../src/contexts/ApplicationsProvider.tsx | 21 ++----- .../src/contexts/DiracXWebProviders.tsx | 16 +++++- .../stories/Dashboard.stories.tsx | 2 +- .../diracx-web/src/app/(dashboard)/layout.tsx | 35 +++++------- .../extensions/src/app/(dashboard)/layout.tsx | 55 +++++++------------ packages/extensions/src/app/auth/layout.tsx | 5 ++ ...{ApplicationList.ts => applicationList.ts} | 0 packages/extensions/test/e2e/loginOut.cy.ts | 4 +- .../extensions/test/e2e/ownerMonitor.cy.ts | 12 +++- 15 files changed, 101 insertions(+), 85 deletions(-) rename packages/diracx-web-components/src/components/{ApplicationList.ts => applicationList.ts} (100%) create mode 100644 packages/diracx-web-components/src/components/defaultDashboard.ts rename packages/extensions/src/gubbins/{ApplicationList.ts => applicationList.ts} (100%) diff --git a/.github/workflows/diracx-web-test.yml b/.github/workflows/diracx-web-test.yml index fe2c82b0..0a58f5dc 100644 --- a/.github/workflows/diracx-web-test.yml +++ b/.github/workflows/diracx-web-test.yml @@ -25,7 +25,7 @@ jobs: - name: Clone source run: | cd .. - git clone https://github.com/aldbr/diracx-charts.git -b main_FIX_diracx-web-install-resources + git clone https://github.com/DIRACGrid/diracx-charts.git - name: Start demo run: | diff --git a/.github/workflows/gubbins-test.yml b/.github/workflows/gubbins-test.yml index 0cd2114c..aaaa8382 100644 --- a/.github/workflows/gubbins-test.yml +++ b/.github/workflows/gubbins-test.yml @@ -53,7 +53,7 @@ jobs: # standalone setup. # prepare-gubbins-backend: runs-on: ubuntu-latest - if: github.event_name == 'push' #${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} + if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} defaults: run: # We need extglob for REFERENCE_BRANCH substitution @@ -152,7 +152,7 @@ jobs: prepare-gubbins-frontend-as-a-standalone: runs-on: ubuntu-latest - if: github.event_name == 'push' #${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} + if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} steps: - uses: actions/checkout@v4 @@ -246,14 +246,14 @@ jobs: run-demo: runs-on: ubuntu-latest needs: [prepare-gubbins-frontend-as-a-standalone, prepare-gubbins-backend] - if: github.event_name == 'push' #github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' + if: github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' steps: - uses: actions/checkout@v4 - name: Clone source run: | cd .. - git clone https://github.com/TheauW/diracx-charts.git -b twartel-fix-ci + git clone https://github.com/DIRACGrid/diracx-charts.git # ========================================================================# # WARNING: In your CI/CD pipeline, you should remove the following steps # @@ -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 \ No newline at end of file diff --git a/docs/developer/create_application.md b/docs/developer/create_application.md index 8964e4b1..52b552b6 100644 --- a/docs/developer/create_application.md +++ b/docs/developer/create_application.md @@ -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 diff --git a/packages/diracx-web-components/src/components/ApplicationList.ts b/packages/diracx-web-components/src/components/applicationList.ts similarity index 100% rename from packages/diracx-web-components/src/components/ApplicationList.ts rename to packages/diracx-web-components/src/components/applicationList.ts diff --git a/packages/diracx-web-components/src/components/defaultDashboard.ts b/packages/diracx-web-components/src/components/defaultDashboard.ts new file mode 100644 index 00000000..b04b6f10 --- /dev/null +++ b/packages/diracx-web-components/src/components/defaultDashboard.ts @@ -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", + }, + ], + }, +]; diff --git a/packages/diracx-web-components/src/components/index.ts b/packages/diracx-web-components/src/components/index.ts index a093c1e5..f5da5865 100644 --- a/packages/diracx-web-components/src/components/index.ts +++ b/packages/diracx-web-components/src/components/index.ts @@ -1,5 +1,5 @@ // Application list -export { applicationList } from "./ApplicationList"; +export { applicationList } from "./applicationList"; // Dashboard Layout export * from "./DashboardLayout"; diff --git a/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx b/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx index af97ee87..c0996263 100644 --- a/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx +++ b/packages/diracx-web-components/src/contexts/ApplicationsProvider.tsx @@ -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"; @@ -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 @@ -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 diff --git a/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx b/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx index 323b3502..856a7e2c 100644 --- a/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx +++ b/packages/diracx-web-components/src/contexts/DiracXWebProviders.tsx @@ -1,5 +1,8 @@ "use client"; +import type { ApplicationMetadata, DashboardGroup } from "../types"; + +import { OIDCSecure } from "../components"; import { OIDCConfigurationProvider, ThemeProvider, @@ -12,6 +15,8 @@ interface DiracXWebProvidersProps { getPath: () => string; setPath: (path: string) => void; getSearchParams: () => URLSearchParams; + appList?: ApplicationMetadata[]; + defaultUserDashboard?: DashboardGroup[]; } export function DiracXWebProviders({ @@ -19,6 +24,8 @@ export function DiracXWebProviders({ getPath, setPath, getSearchParams, + appList, + defaultUserDashboard, }: DiracXWebProvidersProps) { return ( @@ -27,8 +34,13 @@ export function DiracXWebProviders({ setPath={setPath} getSearchParams={getSearchParams} > - - {children} + + + {children} + diff --git a/packages/diracx-web-components/stories/Dashboard.stories.tsx b/packages/diracx-web-components/stories/Dashboard.stories.tsx index be3d3e3f..1a05227c 100644 --- a/packages/diracx-web-components/stories/Dashboard.stories.tsx +++ b/packages/diracx-web-components/stories/Dashboard.stories.tsx @@ -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"; diff --git a/packages/diracx-web/src/app/(dashboard)/layout.tsx b/packages/diracx-web/src/app/(dashboard)/layout.tsx index 3e2f29e2..0222f171 100644 --- a/packages/diracx-web/src/app/(dashboard)/layout.tsx +++ b/packages/diracx-web/src/app/(dashboard)/layout.tsx @@ -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({ @@ -25,22 +22,20 @@ export default function DashboardLayout({ }} getSearchParams={() => searchParams} > - - - - {children} - - - + + + {children} + + ); diff --git a/packages/extensions/src/app/(dashboard)/layout.tsx b/packages/extensions/src/app/(dashboard)/layout.tsx index b15d764d..1f464574 100644 --- a/packages/extensions/src/app/(dashboard)/layout.tsx +++ b/packages/extensions/src/app/(dashboard)/layout.tsx @@ -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 @@ -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 */} - - {/* OIDCSecure is used to make sure the user is authenticated before accessing the dashboard */} - - {/* Dashboard is the main layout for the applications, you can optionally give it a custom logo URL and a drawer width */} - - - {children} - - - - + {/* Dashboard is the main layout for the applications, you can optionally give it a custom logo URL and a drawer width */} + + + {children} + + ); } diff --git a/packages/extensions/src/app/auth/layout.tsx b/packages/extensions/src/app/auth/layout.tsx index 7e563ffc..1a573ab0 100644 --- a/packages/extensions/src/app/auth/layout.tsx +++ b/packages/extensions/src/app/auth/layout.tsx @@ -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({ @@ -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} diff --git a/packages/extensions/src/gubbins/ApplicationList.ts b/packages/extensions/src/gubbins/applicationList.ts similarity index 100% rename from packages/extensions/src/gubbins/ApplicationList.ts rename to packages/extensions/src/gubbins/applicationList.ts diff --git a/packages/extensions/test/e2e/loginOut.cy.ts b/packages/extensions/test/e2e/loginOut.cy.ts index c3994eb6..58494cb9 100644 --- a/packages/extensions/test/e2e/loginOut.cy.ts +++ b/packages/extensions/test/e2e/loginOut.cy.ts @@ -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", () => { @@ -43,6 +43,8 @@ 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.visit("/"); cy.contains("Owners").should("exist"); // Click on the user avatar diff --git a/packages/extensions/test/e2e/ownerMonitor.cy.ts b/packages/extensions/test/e2e/ownerMonitor.cy.ts index e4595a7e..94046ed6 100644 --- a/packages/extensions/test/e2e/ownerMonitor.cy.ts +++ b/packages/extensions/test/e2e/ownerMonitor.cy.ts @@ -1,6 +1,6 @@ /// -describe("Job Monitor", () => { +describe("Owner Monitor", () => { beforeEach(() => { cy.session("login", () => { cy.visit("/auth"); @@ -23,10 +23,11 @@ describe("Job Monitor", () => { '[{"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", () => { - cy.wait(20000); cy.get("header").contains("Owner Monitor").should("be.visible"); }); @@ -51,8 +52,13 @@ describe("Job Monitor", () => { }); /** Column interactions */ - it("should hide/show columns", () => { + // Type the new owner name + cy.get('[data-testid="owner-name-input"]').type("Josephine"); + + // Click the Add Owner button + cy.contains("button", "Add Owner").click(); + // Click on the visibility icon cy.get('[data-testid="VisibilityIcon"] > path').click(); cy.get('[data-testid="column-visibility-popover"]').should("be.visible"); From c93d4cf8e9cc914bb06c4c16b35d2748861b6f5b Mon Sep 17 00:00:00 2001 From: aldbr Date: Thu, 10 Jul 2025 16:03:47 +0200 Subject: [PATCH 3/3] fix: owner monitor --- .../gubbins/components/OwnerMonitor/OwnerMonitor.tsx | 10 +++++++--- packages/extensions/test/e2e/ownerMonitor.cy.ts | 6 ------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/extensions/src/gubbins/components/OwnerMonitor/OwnerMonitor.tsx b/packages/extensions/src/gubbins/components/OwnerMonitor/OwnerMonitor.tsx index 6dc9c552..ef49e8e0 100644 --- a/packages/extensions/src/gubbins/components/OwnerMonitor/OwnerMonitor.tsx +++ b/packages/extensions/src/gubbins/components/OwnerMonitor/OwnerMonitor.tsx @@ -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, @@ -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([ @@ -53,7 +53,7 @@ export default function OwnerMonitor() { } finally { setIsLoading(false); } - }; + }, [accessToken]); // Handle adding a new owner const handleAddOwner = async () => { @@ -91,6 +91,10 @@ export default function OwnerMonitor() { onPaginationChange: setPagination, }); + useEffect(() => { + fetchOwners(); + }, [fetchOwners]); + return ( { /** Column interactions */ it("should hide/show columns", () => { - // Type the new owner name - cy.get('[data-testid="owner-name-input"]').type("Josephine"); - - // Click the Add Owner button - cy.contains("button", "Add Owner").click(); - // Click on the visibility icon cy.get('[data-testid="VisibilityIcon"] > path').click(); cy.get('[data-testid="column-visibility-popover"]').should("be.visible");