Skip to content

Commit

Permalink
feat(ui-test): add Cypress setup with TypeScript support for E2E and …
Browse files Browse the repository at this point in the history
…component testing
  • Loading branch information
hdinia committed Jan 24, 2025
1 parent 5c3f165 commit 7065686
Show file tree
Hide file tree
Showing 9 changed files with 1,868 additions and 94 deletions.
38 changes: 38 additions & 0 deletions webapp/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2025, RTE (https://www.rte-france.com)
*
* See AUTHORS.txt
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of the Antares project.
*/

import { defineConfig } from "cypress";
import path from "path";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default defineConfig({
e2e: {
supportFile: "cypress/support/e2e.ts",
baseUrl: "http://localhost:3000",
viewportWidth: 1280,
viewportHeight: 720,
},
component: {
supportFile: "cypress/support/component.ts",
devServer: {
framework: "react",
bundler: "vite",
viteConfig: {
configFile: path.resolve(__dirname, "vite.config.ts"),
},
},
},
});
71 changes: 71 additions & 0 deletions webapp/cypress/e2e/studies.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright (c) 2025, RTE (https://www.rte-france.com)
*
* See AUTHORS.txt
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of the Antares project.
*/

describe("Studies Page", () => {
beforeEach(() => {
// Mock API response for studies
cy.intercept("GET", "/v1/studies", {
statusCode: 200,
body: [
{ id: "1", name: "Study 1", description: "First study" },
{ id: "2", name: "Study 2", description: "Second study" },
],
}).as("getStudies");

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

it("should display the studies page correctly", () => {
// Check page title
cy.get("h1").should("contain", "Studies");

// Check header elements
cy.get("header").should("contain", "Global Studies");
cy.get('button[aria-label="Filter"]').should("exist");

// Check side navigation
cy.get("nav").within(() => {
cy.contains("All Studies").should("exist");
cy.contains("Favorites").should("exist");
});

// Verify studies list
cy.get('[data-testid="studies-list"]').within(() => {
cy.contains("Study 1").should("exist");
cy.contains("Study 2").should("exist");
});
});

it("should handle loading state", () => {
// Delay the API response to test loading state
cy.intercept("GET", "/v1/studies", (req) => {
req.reply({
delay: 1000,
body: [],
});
}).as("delayedStudies");

cy.get('[data-testid="loading-spinner"]').should("exist");
});

it("should handle error state", () => {
// Force API error
cy.intercept("GET", "/v1/studies", {
forceNetworkError: true,
}).as("errorStudies");

cy.contains("Failed to load studies").should("exist");
cy.get("button").contains("Refresh").should("exist");
});
});
32 changes: 32 additions & 0 deletions webapp/cypress/support/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2025, RTE (https://www.rte-france.com)
*
* See AUTHORS.txt
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of the Antares project.
*/

import { mount } from "cypress/react";
import "@testing-library/cypress/add-commands";

declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}
}

declare namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}

Cypress.Commands.add("mount", mount);
27 changes: 27 additions & 0 deletions webapp/cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2025, RTE (https://www.rte-france.com)
*
* See AUTHORS.txt
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*
* This file is part of the Antares project.
*/

import "@testing-library/cypress/add-commands";

declare global {
namespace Cypress {
interface Chainable {
login(username: string, password: string): Chainable<void>;
}
}
}

Cypress.Commands.add("login", (username, password) => {
// TODO: add login command logic
});
11 changes: 11 additions & 0 deletions webapp/cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["cypress", "@testing-library/cypress"],
"baseUrl": "..",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["**/*.ts"]
}
12 changes: 12 additions & 0 deletions webapp/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import jsdocPlugin from "eslint-plugin-jsdoc";
import prettierPluginRecommended from "eslint-plugin-prettier/recommended";
import licenseHeaderPlugin from "eslint-plugin-license-header";
import reactRefreshPlugin from "eslint-plugin-react-refresh";
import pluginCypress from "eslint-plugin-cypress/flat";

export default [
// Must be defined here to be applied to all configurations.
Expand All @@ -41,6 +42,7 @@ export default [
},
reactPlugin.configs.flat["jsx-runtime"],
jsdocPlugin.configs["flat/recommended-typescript"],
pluginCypress.configs.recommended,
prettierPluginRecommended, // Must be the last one
{
languageOptions: {
Expand All @@ -49,15 +51,25 @@ export default [
globals: {
...globals.browser,
...globals.es2022,
...globals.cypress,
},
},
plugins: {
"license-header": licenseHeaderPlugin,
"react-hooks": reactHookPlugin,
"react-refresh": reactRefreshPlugin,
cypress: pluginCypress,
},
rules: {
...reactHookPlugin.configs.recommended.rules,
// Disable namespace rule for Cypress files
"@typescript-eslint/no-namespace": [
"error",
{
allowDeclarations: true,
allowDefinitionFiles: true,
},
],
"@typescript-eslint/array-type": ["error", { default: "array-simple" }],
"@typescript-eslint/no-restricted-imports": [
"error",
Expand Down
Loading

0 comments on commit 7065686

Please sign in to comment.