Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
hdinia authored and TheoPascoli committed Jan 27, 2025
1 parent a31f9c1 commit 6f5f793
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
@@ -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.
@@ -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: {
@@ -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",
1,756 changes: 1,663 additions & 93 deletions webapp/package-lock.json

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion webapp/package.json
Original file line number Diff line number Diff line change
@@ -11,7 +11,12 @@
"lint": "tsc --noEmit && eslint . --report-unused-disable-directives",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui"
"test:ui": "vitest --ui",
"cy:open": "cypress open --e2e",
"cy:run": "cypress run --e2e",
"test:e2e": "start-server-and-test dev http://localhost:3000 cy:run",
"test:component": "cypress open --component",
"test:ci": "cypress run --component --e2e"
},
"dependencies": {
"@emotion/react": "11.13.3",
@@ -76,6 +81,7 @@
},
"devDependencies": {
"@eslint/js": "9.18.0",
"@testing-library/cypress": "10.0.3",
"@testing-library/jest-dom": "6.5.0",
"@testing-library/react": "16.0.1",
"@testing-library/user-event": "14.5.2",
@@ -105,8 +111,10 @@
"@vitejs/plugin-react-swc": "3.7.0",
"@vitest/coverage-v8": "2.1.1",
"@vitest/ui": "2.1.1",
"cypress": "14.0.0",
"eslint": "9.18.0",
"eslint-config-prettier": "10.0.1",
"eslint-plugin-cypress": "4.1.0",
"eslint-plugin-jsdoc": "50.6.1",
"eslint-plugin-license-header": "0.6.1",
"eslint-plugin-prettier": "5.2.1",
5 changes: 5 additions & 0 deletions webapp/vite.config.ts
Original file line number Diff line number Diff line change
@@ -66,6 +66,11 @@ export default defineConfig(({ mode }) => {
environment: "jsdom",
css: true,
setupFiles: "./src/tests/setup.ts",
server: {
deps: {
inline: ["cypress"], // Allow Cypress to inline dependencies
},
},
},
};
});

0 comments on commit 6f5f793

Please sign in to comment.