Skip to content

Commit f8e6b09

Browse files
committed
front: refacto old e2e tests
Signed-off-by: maymanaf <med.aymen.naf@gmail.com>
1 parent d768e04 commit f8e6b09

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1789
-2235
lines changed

front/src/applications/operationalStudies/components/BreadCrumbs.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export default function BreadCrumbs({ project, study, scenario }: Props) {
3131

3232
{project && study && (
3333
<>
34-
<div className="text-truncate" title={project.name}>
34+
<div data-testid="project-breadcrumbs" className="text-truncate" title={project.name}>
3535
<Link to={`/operational-studies/projects/${project.id}`}> {project.name}</Link>
3636
</div>
3737
<span className="text-muted">

front/src/applications/operationalStudies/views/Project.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ export default function Project() {
222222
<div className="project-details-title-name">
223223
{project.name}
224224
<button
225+
data-testid="project-update-button"
225226
className="project-details-title-modify-button"
226227
type="button"
227228
onClick={() =>

front/src/common/BootstrapSNCF/CardSNCF/CardSNCF.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ const Card = ({ link, img, title, disabledLink = false, openInNewTab = false }:
2020
>
2121
<img className="card-img-top" alt={title} src={img} />
2222
<div className="card-body text-center">
23-
<h5 className="card-title mb-0 text-base font-weight-normal">{title}</h5>
23+
<h5 data-testid="page-title" className="card-title mb-0 text-base font-weight-normal">
24+
{title}
25+
</h5>
2426
</div>
2527
</Link>
2628
);

front/src/common/BootstrapSNCF/ChipsSNCF.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ export default function ChipsSNCF({
3838
return (
3939
<div role="list" key={nextId()}>
4040
<div className="chips-group" role="listitem">
41-
<span className={`chips chips-label pr-1 ${chipColor}`}>{label}</span>
41+
<span
42+
data-testid="scenario-details-tag"
43+
className={`chips chips-label pr-1 ${chipColor}`}
44+
>
45+
{label}
46+
</span>
4247
<button
4348
type="button"
4449
className={`chips chips-btn chips-only-icon ${chipColor}`}

front/src/common/BootstrapSNCF/NavBarSNCF.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const LegacyNavBarSNCF = ({ appName, logo = getLogo() }: Props) => {
3434
<div className="mastheader">
3535
<div className="mastheader-logo flex-grow-0">
3636
<Link to="/">
37-
<img src={logo} alt="OSRD Logo" />
37+
<img src={logo} data-testid="osrd-logo" alt="OSRD Logo" />
3838
</Link>
3939
</div>
4040
<header role="banner" className="mastheader-title d-flex flex-grow-1">

front/src/modules/infra/components/InfraSelector/InfraSelectorModalBodyStandard.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export default function InfraSelectorModalBodyStandard({
8484
<div className="text-center small text-muted infras-count">
8585
{infrasList && t('infraManagement:infrasFound', { count: infrasList.length })}
8686
</div>
87-
<div className="infraslist" data-testid="infraslist">
87+
<div className="infraslist" data-testid="infra-list">
8888
{infrasList.map((infra) => (
8989
<button
9090
data-testid={`infraslist-item-${infra.id}`}

front/src/modules/scenario/components/AddOrEditScenarioModal.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ export default function AddOrEditScenarioModal({
368368
<div className="d-flex justify-content-end w-100 mt-3">
369369
{editionMode && (
370370
<button
371-
data-testid="deleteScenario"
371+
data-testid="delete-scenario"
372372
className="btn btn-sm btn-outline-danger mr-auto"
373373
type="button"
374374
onClick={removeScenario}

front/src/modules/scenario/components/ScenarioCardEmpty.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default function StudyCard() {
1010

1111
return (
1212
<div
13-
data-testid="addScenario"
13+
data-testid="add-scenario-button"
1414
className="scenario-card empty"
1515
role="button"
1616
tabIndex={0}

front/tests/001-home-page.spec.ts

+32-36
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,59 @@
1-
import { test, expect } from '@playwright/test';
2-
31
import HomePage from './pages/home-page-model';
2+
import { test, expect } from './playwright-fixture';
3+
import enTranslations from '../public/locales/en/home/home.json';
4+
import frTranslations from '../public/locales/fr/home/home.json';
45

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

9-
test.beforeEach(async ({ page }) => {
10-
// Create an instance of the HomePage class
9+
test.beforeEach('Navigate to the home page', async ({ page }) => {
1110
homePage = new HomePage(page);
12-
// Go to the home page of OSRD
1311
await homePage.goToHomePage();
1412
});
1513

16-
test.afterEach(async () => {
17-
// Navigate back to the home page of OSRD
14+
test.afterEach('Returns to the home page', async () => {
1815
await homePage.backToHomePage();
1916
});
2017

21-
// Test that the home page of OSRD displays links to other pages
22-
test('should display links in the home page', async () => {
23-
await homePage.getDisplayLinks();
18+
/** *************** Test 1 **************** */
19+
test('Verify the links for different pages in Home Page', async ({ OSRDLanguage }) => {
20+
// Determine the correct translations based on the selected language
21+
const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
22+
23+
// List of expected links on the home page
24+
const expectedLinks = [
25+
translations.operationalStudies,
26+
translations.stdcm,
27+
translations.editor,
28+
translations.rollingStockEditor,
29+
translations.map,
30+
];
31+
32+
// Verify that the displayed links match the expected ones
33+
await expect(homePage.linksTitle).toHaveText(expectedLinks);
2434
});
2535

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

33-
test('should be correctly redirected to the "Map" page after clicking on the link', async () => {
34-
// Navigate to the "Map" page
42+
/** *************** Test 3 **************** */
43+
test('Verify redirection toto the Map page', async () => {
3544
await homePage.goToCartoPage();
36-
37-
// Check that the URL of the page matches the expected pattern
3845
await expect(homePage.page).toHaveURL(/.*\/map/);
3946
});
4047

41-
test('should be correctly redirected to the "Editor" page after clicking on the link', async () => {
42-
// Navigate to the "Editor" page
48+
/** *************** Test 4 **************** */
49+
test('Verify redirection to to the Infrastructure editor page', async () => {
4350
await homePage.goToEditorPage();
44-
45-
// Check that the URL of the page matches the expected pattern
4651
await expect(homePage.page).toHaveURL(/.*\/editor\/*/);
4752
});
4853

49-
test('should be correctly redirected to the "STDCM" page after clicking on the link', async ({
50-
context,
51-
}) => {
52-
// Start waiting for new page before clicking. Note no await.
53-
const pagePromise = context.waitForEvent('page');
54-
55-
// Navigate to the "STDCM" page
56-
await homePage.goToSTDCMPage();
57-
58-
const newPage = await pagePromise;
59-
60-
// Check that the URL of the page matches the expected pattern
61-
await expect(newPage).toHaveURL(/.*\/stdcm/);
54+
/** *************** Test 5 **************** */
55+
test('Verify redirection to to the STDCM page', async ({ context }) => {
56+
const stdcmPage = await homePage.goToSTDCMPage(context);
57+
await expect(stdcmPage).toHaveURL(/.*\/stdcm/);
6258
});
6359
});
+66-106
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,105 @@
1-
import { test, expect } from '@playwright/test';
1+
import { test } from '@playwright/test';
22
import { v4 as uuidv4 } from 'uuid';
33

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

66
import projectData from './assets/operationStudies/project.json';
7-
import CommonPage from './pages/common-page-model';
87
import HomePage from './pages/home-page-model';
98
import ProjectPage from './pages/project-page-model';
109
import { deleteApiRequest, getApiRequest, postApiRequest } from './utils/api-setup';
1110

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

14-
test.beforeEach(async () => {
15-
project = await postApiRequest('/api/projects/', {
16-
...projectData,
17-
name: `${projectData.name} ${uuidv4()}`,
18-
budget: 1234567890,
14+
test.beforeEach('Create a new project using the API', async ({ page }) => {
15+
project = await postApiRequest('/api/projects/', {
16+
...projectData,
17+
name: `${projectData.name} ${uuidv4()}`, // Generate a unique name with UUID
18+
budget: 1234567890, // Assign a predefined budget for testing
19+
});
20+
// Navigate to the Operational Studies projects page
21+
await page.goto('/operational-studies/projects');
1922
});
20-
});
2123

22-
test.afterEach(async () => {
23-
await deleteApiRequest(`/api/projects/${project.id}/`);
24-
});
24+
test.afterEach('Delete the project', async () => {
25+
await deleteApiRequest(`/api/projects/${project.id}/`);
26+
});
2527

26-
test.describe('Test if operationnal study : project workflow is working properly', () => {
28+
/** *************** Test 1 **************** */
2729
test('Create a new project', async ({ page }) => {
28-
const homePage = new HomePage(page);
2930
const projectPage = new ProjectPage(page);
30-
const commonPage = new CommonPage(page);
31-
32-
await homePage.goToHomePage();
33-
await homePage.goToOperationalStudiesPage();
34-
await expect(projectPage.getAddProjectBtn).toBeVisible();
35-
await projectPage.openProjectModalCreation();
3631

32+
// Define a unique project name for the test
3733
const projectName = `${projectData.name} ${uuidv4()}`;
38-
await projectPage.setProjectName(projectName);
39-
40-
await projectPage.setProjectDescription(projectData.description);
41-
42-
await projectPage.setProjectObjectives(projectData.objectives);
43-
44-
await projectPage.setProjectFunder(projectData.funders);
45-
46-
await projectPage.setProjectBudget(projectData.budget);
47-
48-
await commonPage.setTag(projectData.tags[0]);
49-
await commonPage.setTag(projectData.tags[1]);
50-
await commonPage.setTag(projectData.tags[2]);
51-
52-
const createButton = homePage.page.getByTestId('createProject');
53-
await createButton.click();
54-
await homePage.page.waitForURL('**/projects/*');
55-
expect(await projectPage.getProjectName.textContent()).toContain(projectName);
56-
expect(await projectPage.getProjectDescription.textContent()).toContain(
57-
projectData.description
58-
);
59-
const objectives = await projectPage.getProjectObjectives.textContent();
60-
expect(objectives).not.toEqual(null);
61-
if (objectives !== null)
62-
expect(objectives.replace(/[^A-Za-z0-9]/g, '')).toContain(
63-
(project.objectives ?? '').replace(/[^A-Za-z0-9]/g, '')
64-
);
65-
expect(await projectPage.getProjectFinancialsInfos.textContent()).toContain(
66-
projectData.funders
67-
);
68-
const budget = await projectPage.getProjectFinancialsAmount.textContent();
69-
expect(budget).not.toEqual(null);
70-
if (budget !== null) expect(budget.replace(/[^0-9]/g, '')).toContain(projectData.budget);
71-
const tags = await projectPage.getProjectTags.textContent();
72-
expect(tags).toContain(projectData.tags.join(''));
7334

35+
// Create a new project using the project page model and json data
36+
await projectPage.createOrUpdateProject({
37+
name: projectName,
38+
description: projectData.description,
39+
objectives: projectData.objectives,
40+
funders: projectData.funders,
41+
budget: projectData.budget,
42+
tags: projectData.tags,
43+
});
44+
45+
// Validate that the project was created with the correct data
46+
await projectPage.validateProjectData({
47+
name: projectName,
48+
description: projectData.description,
49+
objectives: projectData.objectives,
50+
funders: projectData.funders,
51+
budget: projectData.budget,
52+
tags: projectData.tags,
53+
});
54+
55+
// Fetch all projects via the API and find the test project by name
7456
const projects = await getApiRequest('/api/projects/');
7557
const actualTestProject = projects.results.find((p: Project) => p.name === projectName);
76-
77-
const deleteProject = await deleteApiRequest(`/api/projects/${actualTestProject.id}/`);
78-
expect(deleteProject.status()).toEqual(204);
58+
// Delete the created project
59+
await deleteApiRequest(`/api/projects/${actualTestProject.id}/`);
7960
});
8061

81-
test(' update a project', async ({ page }) => {
62+
/** *************** Test 2 **************** */
63+
test('Update an existing project', async ({ page }) => {
8264
const homePage = new HomePage(page);
8365
const projectPage = new ProjectPage(page);
84-
const commonPage = new CommonPage(page);
85-
86-
await page.goto('/operational-studies/projects');
8766

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

90-
await projectPage.openProjectModalUpdate();
91-
92-
await projectPage.setProjectName(`${project.name} (updated)`);
93-
94-
await projectPage.setProjectDescription(`${project.description} (updated)`);
95-
96-
await projectPage.setProjectObjectives(`updated`);
97-
98-
await projectPage.setProjectFunder(`${project.funders} (updated)`);
99-
100-
await projectPage.setProjectBudget('123456789');
101-
102-
await commonPage.setTag('update-tag');
103-
104-
await projectPage.clickProjectUpdateConfirmBtn();
105-
70+
// Update the project data and save it
71+
await projectPage.createOrUpdateProject({
72+
name: `${project.name} (updated)`,
73+
description: `${project.description} (updated)`,
74+
objectives: `${projectData.objectives} (updated)`,
75+
funders: `${project.funders} (updated)`,
76+
budget: '123456789',
77+
tags: ['update-tag'],
78+
isUpdate: true, // Indicate that this is an update
79+
});
80+
81+
// Navigate back to the Operational Studies page via the home page
10682
await homePage.goToHomePage();
10783
await homePage.goToOperationalStudiesPage();
10884

85+
// Reopen the updated project and validate the updated data
10986
await projectPage.openProjectByTestId(`${project.name} (updated)`);
110-
111-
expect(await projectPage.getProjectName.innerText()).toContain(`${project.name} (updated)`);
112-
expect(await projectPage.getProjectDescription.textContent()).toContain(
113-
`${project.description} (updated)`
114-
);
115-
expect(await projectPage.getProjectObjectives.textContent()).toContain('updated');
116-
expect(await projectPage.getProjectFinancialsInfos.textContent()).toContain(
117-
`${project.funders} (updated)`
118-
);
119-
const budget = await projectPage.getProjectFinancialsAmount.textContent();
120-
expect(budget).not.toEqual(null);
121-
if (budget !== null) expect(budget.replace(/[^0-9]/g, '')).toContain('123456789');
122-
expect(await projectPage.getProjectTags.textContent()).toContain(
123-
`${project.tags.join('')}update-tag`
124-
);
125-
126-
const deleteProject = await deleteApiRequest(`/api/projects/${project.id}/`);
127-
expect(deleteProject.status()).toEqual(204);
87+
await projectPage.validateProjectData({
88+
name: `${project.name} (updated)`,
89+
description: `${project.description} (updated)`,
90+
objectives: `${projectData.objectives} (updated)`,
91+
funders: `${project.funders} (updated)`,
92+
budget: '123456789',
93+
tags: ['update-tag'],
94+
});
12895
});
12996

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

133-
await page.goto('/operational-studies/projects');
134-
101+
// Find the project by name and delete it using the page model
135102
await projectPage.clickProjectByName(project.name);
136-
await projectPage.checkLabelProjectSelected();
137-
await expect(projectPage.getProjectDeleteBtn).not.toBeEmpty();
138-
await projectPage.clickProjectDeleteBtn();
139-
await expect(projectPage.getProjectDeleteConfirmBtn).toBeVisible();
140-
await projectPage.clickProjectDeleteConfirmBtn();
141-
await expect(projectPage.getProjectDeleteConfirmBtn).not.toBeVisible();
142-
await expect(projectPage.getProjectDeleteBtn).not.toBeVisible();
143-
await expect(projectPage.getProjectByName(project.name)).not.toBeVisible();
103+
await projectPage.deleteProject(project.name);
144104
});
145105
});

0 commit comments

Comments
 (0)