Skip to content

Commit

Permalink
front: refacto old e2e tests
Browse files Browse the repository at this point in the history
Signed-off-by: maymanaf <[email protected]>

front: add op simulation settings e2e test

Signed-off-by: maymanaf <[email protected]>
  • Loading branch information
Maymanaf committed Oct 18, 2024
1 parent 093d78f commit a43ce7c
Show file tree
Hide file tree
Showing 51 changed files with 2,555 additions and 2,616 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function BreadCrumbs({ project, study, scenario }: Props) {

{project && study && (
<>
<div className="text-truncate" title={project.name}>
<div data-testid="project-breadcrumbs" className="text-truncate" title={project.name}>
<Link to={`/operational-studies/projects/${project.id}`}> {project.name}</Link>
</div>
<span className="text-muted">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ const Project = () => {
<div className="project-details-title-name">
{project.name}
<button
data-testid="project-update-button"
className="project-details-title-modify-button"
type="button"
onClick={() =>
Expand Down
4 changes: 3 additions & 1 deletion front/src/common/BootstrapSNCF/CardSNCF/CardSNCF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ const Card = ({ link, img, title, disabledLink = false, openInNewTab = false }:
>
<img className="card-img-top" alt={title} src={img} />
<div className="card-body text-center">
<h5 className="card-title mb-0 text-base font-weight-normal">{title}</h5>
<h5 data-testid="page-title" className="card-title mb-0 text-base font-weight-normal">
{title}
</h5>
</div>
</Link>
);
Expand Down
7 changes: 6 additions & 1 deletion front/src/common/BootstrapSNCF/ChipsSNCF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ export default function ChipsSNCF({
return (
<div role="list" key={nextId()}>
<div className="chips-group" role="listitem">
<span className={`chips chips-label pr-1 ${chipColor}`}>{label}</span>
<span
data-testid="scenario-details-tag"
className={`chips chips-label pr-1 ${chipColor}`}
>
{label}
</span>
<button
type="button"
className={`chips chips-btn chips-only-icon ${chipColor}`}
Expand Down
2 changes: 1 addition & 1 deletion front/src/common/BootstrapSNCF/NavBarSNCF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const LegacyNavBarSNCF = ({ appName, logo = getLogo() }: Props) => {
<div className="mastheader">
<div className="mastheader-logo flex-grow-0">
<Link to="/">
<img src={logo} alt="OSRD Logo" />
<img src={logo} data-testid="osrd-logo" alt="OSRD Logo" />
</Link>
</div>
<header role="banner" className="mastheader-title d-flex flex-grow-1">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default function InfraSelectorModalBodyStandard({
<div className="text-center small text-muted infras-count">
{infrasList && t('infraManagement:infrasFound', { count: infrasList.length })}
</div>
<div className="infraslist" data-testid="infraslist">
<div className="infraslist" data-testid="infra-list">
{infrasList.map((infra) => (
<button
data-testid={`infraslist-item-${infra.id}`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ const AddOrEditScenarioModal = ({ editionMode = false, scenario }: AddOrEditScen
<div className="d-flex justify-content-end w-100 mt-3">
{editionMode && (
<button
data-testid="deleteScenario"
data-testid="delete-scenario"
className="btn btn-sm btn-outline-danger mr-auto"
type="button"
onClick={removeScenario}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function StudyCard() {

return (
<div
data-testid="addScenario"
data-testid="add-scenario-button"
className="scenario-card empty"
role="button"
tabIndex={0}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { describe, it, expect } from 'vitest';

import { LIST_VALUES, CHART_AXES } from 'modules/simulationResult/consts';

import simulationTrain from '../../../../../../tests/assets/operationStudies/simulationTrain';
import train from '../../../../../../tests/assets/operationStudies/trainExample';
import simulationTrain from '../../../../../assets/operationStudies/simulationTrain';
import train from '../../../../../assets/operationStudies/trainExample';
import { interpolateOnTime, getAxis } from '../ChartHelpers';

describe('interpolateOnTime', () => {
Expand Down
68 changes: 33 additions & 35 deletions front/tests/001-home-page.spec.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,61 @@
import { test, expect } from '@playwright/test';

import HomePage from './pages/home-page-model';
import enTranslations from '../public/locales/en/home/home.json';
import frTranslations from '../public/locales/fr/home/home.json';

// Describe the test suite for the home page of OSRD
test.describe('Home page OSRD', () => {
let homePage: HomePage;

test.beforeEach(async ({ page }) => {
// Create an instance of the HomePage class
let OSRDLanguage: string;
test.beforeEach('Navigate to the home page', async ({ page }) => {
homePage = new HomePage(page);
// Go to the home page of OSRD
await homePage.goToHomePage();
OSRDLanguage = await homePage.getOSRDLanguage();
});

test.afterEach(async () => {
// Navigate back to the home page of OSRD
test.afterEach('Returns to the home page', async () => {
await homePage.backToHomePage();
});

// Test that the home page of OSRD displays links to other pages
test('should display links in the home page', async () => {
await homePage.getDisplayLinks();
/** *************** Test 1 **************** */
test('Verify the links for different pages in Home Page', async () => {
// Determine the correct translations based on the selected language
const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;

// List of expected links on the home page
const expectedLinks = [
translations.operationalStudies,
translations.stdcm,
translations.editor,
translations.rollingStockEditor,
translations.map,
];

// Verify that the displayed links match the expected ones
await expect(homePage.linksTitle).toHaveText(expectedLinks);
});

test('should be correctly redirected to the "Operational Studies" page after clicking on the link', async () => {
// Navigate to the "Operational Studies" page
/** *************** Test 2 **************** */
test('Verify redirection to to the Operational Studies page', async () => {
await homePage.goToOperationalStudiesPage();
// Check that the URL of the page matches the expected pattern
await expect(homePage.page).toHaveURL(/.*\/operational-studies/);
await expect(homePage.page).toHaveURL(/.*\/operational-studies/); // Check the URL
});

test('should be correctly redirected to the "Map" page after clicking on the link', async () => {
// Navigate to the "Map" page
/** *************** Test 3 **************** */
test('Verify redirection toto the Map page', async () => {
await homePage.goToCartoPage();

// Check that the URL of the page matches the expected pattern
await expect(homePage.page).toHaveURL(/.*\/map/);
});

test('should be correctly redirected to the "Editor" page after clicking on the link', async () => {
// Navigate to the "Editor" page
/** *************** Test 4 **************** */
test('Verify redirection to to the Infrastructure editor page', async () => {
await homePage.goToEditorPage();

// Check that the URL of the page matches the expected pattern
await expect(homePage.page).toHaveURL(/.*\/editor\/*/);
});

test('should be correctly redirected to the "STDCM" page after clicking on the link', async ({
context,
}) => {
// Start waiting for new page before clicking. Note no await.
const pagePromise = context.waitForEvent('page');

// Navigate to the "STDCM" page
await homePage.goToSTDCMPage();

const newPage = await pagePromise;

// Check that the URL of the page matches the expected pattern
await expect(newPage).toHaveURL(/.*\/stdcm/);
/** *************** Test 5 **************** */
test('Verify redirection to to the STDCM page', async ({ context }) => {
const stdcmPage = await homePage.goToSTDCMPage(context);
await expect(stdcmPage).toHaveURL(/.*\/stdcm/);
});
});
181 changes: 68 additions & 113 deletions front/tests/002-project-management.spec.ts
Original file line number Diff line number Diff line change
@@ -1,145 +1,100 @@
import { test, expect } from '@playwright/test';
import { test } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';

import type { Project } from 'common/api/osrdEditoastApi';

import projectData from './assets/operationStudies/project.json';
import CommonPage from './pages/common-page-model';
import HomePage from './pages/home-page-model';
import ProjectPage from './pages/project-page-model';
import { deleteApiRequest, getApiRequest, postApiRequest } from './utils/api-setup';
import { generateUniqueName } from './utils';
import { createProject } from './utils/setup-utils';
import { deleteProject } from './utils/teardown-utils';

let project: Project;
test.describe('Validate the Operational Study Project workflow', () => {
let project: Project;

test.beforeEach(async () => {
project = await postApiRequest('/api/projects/', {
...projectData,
name: `${projectData.name} ${uuidv4()}`,
budget: 1234567890,
test.beforeEach('Navigate to the Operational Studies projects page', async ({ page }) => {
await page.goto('/operational-studies/projects');
});
});

test.afterEach(async () => {
await deleteApiRequest(`/api/projects/${project.id}/`);
});

test.describe('Test if project workflow is working properly', () => {
/** *************** Test 1 **************** */
test('Create a new project', async ({ page }) => {
const homePage = new HomePage(page);
const projectPage = new ProjectPage(page);
const commonPage = new CommonPage(page);

await homePage.goToHomePage();
await homePage.goToOperationalStudiesPage();
await expect(projectPage.getAddProjectBtn).toBeVisible();
await projectPage.openProjectModalCreation();

// Define a unique project name for the test
const projectName = `${projectData.name} ${uuidv4()}`;
await projectPage.setProjectName(projectName);

await projectPage.setProjectDescription(projectData.description);

await projectPage.setProjectObjectives(projectData.objectives);

await projectPage.setProjectFunder(projectData.funders);

await projectPage.setProjectBudget(projectData.budget);

await commonPage.setTag(projectData.tags[0]);
await commonPage.setTag(projectData.tags[1]);
await commonPage.setTag(projectData.tags[2]);

const createButton = homePage.page.getByTestId('createProject');
await createButton.click();
await homePage.page.waitForURL('**/projects/*');
expect(await projectPage.getProjectName.textContent()).toContain(projectName);
expect(await projectPage.getProjectDescription.textContent()).toContain(
projectData.description
);
const objectives = await projectPage.getProjectObjectives.textContent();
expect(objectives).not.toEqual(null);
if (objectives !== null)
expect(objectives.replace(/[^A-Za-z0-9]/g, '')).toContain(
(project.objectives ?? '').replace(/[^A-Za-z0-9]/g, '')
);
expect(await projectPage.getProjectFinancialsInfos.textContent()).toContain(
projectData.funders
);
const budget = await projectPage.getProjectFinancialsAmount.textContent();
expect(budget).not.toEqual(null);
if (budget !== null) expect(budget.replace(/[^0-9]/g, '')).toContain(projectData.budget);
const tags = await projectPage.getProjectTags.textContent();
expect(tags).toContain(projectData.tags.join(''));

const projects = await getApiRequest('/api/projects/');
const actualTestProject = projects.results.find((p: Project) => p.name === projectName);

const deleteProject = await deleteApiRequest(`/api/projects/${actualTestProject.id}/`);
expect(deleteProject.status()).toEqual(204);

// Create a new project using the project page model and json data
await projectPage.createOrUpdateProject({
name: projectName,
description: projectData.description,
objectives: projectData.objectives,
funders: projectData.funders,
budget: projectData.budget,
tags: projectData.tags,
});

// Validate that the project was created with the correct data
await projectPage.validateProjectData({
name: projectName,
description: projectData.description,
objectives: projectData.objectives,
funders: projectData.funders,
budget: projectData.budget,
tags: projectData.tags,
});

// Delete the created project
await deleteProject(projectName);
});

test(' update a project', async ({ page }) => {
/** *************** Test 2 **************** */
test('Update an existing project', async ({ page }) => {
// Create a project
project = await createProject(generateUniqueName('project_test_e2e'));

const homePage = new HomePage(page);
const projectPage = new ProjectPage(page);
const commonPage = new CommonPage(page);

await page.goto('/operational-studies/projects');

// Open the created project by name using the project page model
await projectPage.openProjectByTestId(project.name);

await projectPage.openProjectModalUpdate();

await projectPage.setProjectName(`${project.name} (updated)`);

await projectPage.setProjectDescription(`${project.description} (updated)`);

await projectPage.setProjectObjectives(`updated`);

await projectPage.setProjectFunder(`${project.funders} (updated)`);

await projectPage.setProjectBudget('123456789');

await commonPage.setTag('update-tag');

await projectPage.clickProjectUpdateConfirmBtn();

// Update the project data and save it
await projectPage.createOrUpdateProject({
name: `${project.name} (updated)`,
description: `${project.description} (updated)`,
objectives: `${projectData.objectives} (updated)`,
funders: `${project.funders} (updated)`,
budget: '123456789',
tags: ['update-tag'],
isUpdate: true, // Indicate that this is an update
});

// Navigate back to the Operational Studies page via the home page
await homePage.goToHomePage();
await homePage.goToOperationalStudiesPage();

// Reopen the updated project and validate the updated data
await projectPage.openProjectByTestId(`${project.name} (updated)`);

expect(await projectPage.getProjectName.innerText()).toContain(`${project.name} (updated)`);
expect(await projectPage.getProjectDescription.textContent()).toContain(
`${project.description} (updated)`
);
expect(await projectPage.getProjectObjectives.textContent()).toContain('updated');
expect(await projectPage.getProjectFinancialsInfos.textContent()).toContain(
`${project.funders} (updated)`
);
const budget = await projectPage.getProjectFinancialsAmount.textContent();
expect(budget).not.toEqual(null);
if (budget !== null) expect(budget.replace(/[^0-9]/g, '')).toContain('123456789');
expect(await projectPage.getProjectTags.textContent()).toContain(
`${project.tags.join('')}update-tag`
);

const deleteProject = await deleteApiRequest(`/api/projects/${project.id}/`);
expect(deleteProject.status()).toEqual(204);
await projectPage.validateProjectData({
name: `${project.name} (updated)`,
description: `${project.description} (updated)`,
objectives: `${projectData.objectives} (updated)`,
funders: `${project.funders} (updated)`,
budget: '123456789',
tags: ['update-tag'],
});
// Delete the created project
await deleteProject(`${project.name} (updated)`);
});

/** *************** Test 3 **************** */
test('Delete a project', async ({ page }) => {
const projectPage = new ProjectPage(page);

await page.goto('/operational-studies/projects');
// Create a project
project = await createProject(generateUniqueName('project_test_e2e'));

const projectPage = new ProjectPage(page);
// Find the project by name and delete it using the page model
await projectPage.clickProjectByName(project.name);
await projectPage.checkLabelProjectSelected();
await expect(projectPage.getProjectDeleteBtn).not.toBeEmpty();
await projectPage.clickProjectDeleteBtn();
await expect(projectPage.getProjectDeleteConfirmBtn).toBeVisible();
await projectPage.clickProjectDeleteConfirmBtn();
await expect(projectPage.getProjectDeleteConfirmBtn).not.toBeVisible();
await expect(projectPage.getProjectDeleteBtn).not.toBeVisible();
await expect(projectPage.getProjectByName(project.name)).not.toBeVisible();
await projectPage.deleteProject(project.name);
});
});
Loading

0 comments on commit a43ce7c

Please sign in to comment.