Skip to content

Commit 8478cdc

Browse files
committed
front: update default stdcm page e2e test
Signed-off-by: maymanaf <[email protected]> front: add stdcm simulation sheet e2e test Signed-off-by: maymanaf <[email protected]>
1 parent bcbc767 commit 8478cdc

File tree

8 files changed

+245
-20
lines changed

8 files changed

+245
-20
lines changed

front/package-lock.json

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

front/src/applications/stdcm/components/StdcmForm/StdcmLinkedTrainSearch.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ const StdcmLinkedTrainSearch = ({
5858
disabled={disabled}
5959
name={t(`trainPath.linkedTrain.${linkedTrainType}`)}
6060
title={
61-
<button type="button" onClick={removeLinkedTrainCard}>
61+
<button
62+
data-testid="linked-train-delete-button"
63+
type="button"
64+
onClick={removeLinkedTrainCard}
65+
>
6266
{t('translation:common.delete').toLowerCase()}
6367
</button>
6468
}
@@ -91,6 +95,7 @@ const StdcmLinkedTrainSearch = ({
9195
</div>
9296
{displaySearchButton && (
9397
<button
98+
data-testid="linked-train-search-button"
9499
className="stdcm-linked-train-button"
95100
type="button"
96101
onClick={launchTrainScheduleSearch}

front/tests/006-stdcm.spec.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Infra, TowedRollingStock } from 'common/api/osrdEditoastApi';
22

33
import { electricRollingStockName, fastRollingStockName } from './assets/project-const';
44
import HomePage from './pages/home-page-model';
5+
import STDCMLinkedTrainPage from './pages/stdcm-linked-train-page-model';
56
import STDCMPage, { type ConsistFields } from './pages/stdcm-page-model';
67
import test from './test-logger';
78
import { handleAndVerifyInput, waitForInfraStateToBeCached } from './utils';
@@ -63,12 +64,13 @@ test.describe('Verify stdcm simulation page', () => {
6364
});
6465

6566
/** *************** Test 1 **************** */
66-
test('Verify empty STDCM page', async ({ page }) => {
67-
// Verify visibility of STDCM elements and handle empty via fields
68-
const stdcmPage = new STDCMPage(page);
67+
test('Verify default STDCM page', async ({ page }) => {
68+
// Verify visibility of STDCM elements and handle default fields
69+
const [stdcmPage, stdcmLinkedTrainPage] = [new STDCMPage(page), new STDCMLinkedTrainPage(page)];
6970
await stdcmPage.verifyStdcmElementsVisibility();
70-
await stdcmPage.verifyAllFieldsEmpty();
71-
await stdcmPage.addAndDeleteEmptyVia();
71+
await stdcmPage.verifyAllDefaultPageFields();
72+
await stdcmPage.addAndDeletedDefaultVia();
73+
await stdcmLinkedTrainPage.addAndDeleteDefaultLinkedPath();
7274
});
7375

7476
/** *************** Test 2 **************** */

front/tests/assets/simulation-sheet-const.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import enTranslations from '../../public/locales/en/stdcm-simulation-report-sheet.json';
22
import frTranslations from '../../public/locales/fr/stdcm-simulation-report-sheet.json';
33
import { getLocalizedDateString } from '../utils/date';
4-
import type { Simulation } from '../utils/types';
4+
import type { Simulation } from '../utils/simulationSheet';
55

66
const simulationSheetDetails = (selectedLanguage: string): Simulation => {
77
const translations = selectedLanguage === 'English' ? enTranslations : frTranslations;

front/tests/assets/stdcm-const.ts

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const DEFAULT_DETAILS = {
88
arrivalDate: '17/10/24',
99
arrivalTime: '00:00',
1010
tolerance: '-30/+30',
11+
speedLimitTag: '__PLACEHOLDER__', // value = None
1112
};
1213

1314
export const ORIGIN_DETAILS = {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { expect, type Locator, type Page } from '@playwright/test';
2+
3+
import STDCMPage from './stdcm-page-model';
4+
5+
class STDCMLinkedTrainPage extends STDCMPage {
6+
readonly anteriorLinkedTrainContainer: Locator;
7+
8+
readonly anteriorDeleteLinkedPathButton: Locator;
9+
10+
readonly anteriorLinkedTrainField: Locator;
11+
12+
readonly anteriorLinkedTrainDate: Locator;
13+
14+
readonly anteriorLinkedTrainSearchButton: Locator;
15+
16+
readonly posteriorLinkedTrainContainer: Locator;
17+
18+
readonly posteriorDeleteLinkedPathButton: Locator;
19+
20+
readonly posteriorLinkedTrainField: Locator;
21+
22+
readonly posteriorLinkedTrainDate: Locator;
23+
24+
readonly posteriorLinkedTrainSearchButton: Locator;
25+
26+
constructor(readonly page: Page) {
27+
super(page);
28+
this.anteriorLinkedTrainContainer = page.locator(
29+
'.stdcm-linked-train-search-container.anterior-linked-train'
30+
);
31+
this.anteriorDeleteLinkedPathButton = this.anteriorLinkedTrainContainer.getByTestId(
32+
'linked-train-delete-button'
33+
);
34+
this.anteriorLinkedTrainField = this.anteriorLinkedTrainContainer.locator('#linked-train-id');
35+
this.anteriorLinkedTrainDate = this.anteriorLinkedTrainContainer.locator('#linked-train-date');
36+
this.anteriorLinkedTrainSearchButton = this.anteriorLinkedTrainContainer.getByTestId(
37+
'linked-train-search-button'
38+
);
39+
this.posteriorLinkedTrainContainer = page.locator(
40+
'.stdcm-linked-train-search-container.posterior-linked-train'
41+
);
42+
this.posteriorDeleteLinkedPathButton = this.posteriorLinkedTrainContainer.getByTestId(
43+
'linked-train-delete-button'
44+
);
45+
this.posteriorLinkedTrainField = this.posteriorLinkedTrainContainer.locator('#linked-train-id');
46+
this.posteriorLinkedTrainDate =
47+
this.posteriorLinkedTrainContainer.locator('#linked-train-date');
48+
this.posteriorLinkedTrainSearchButton = this.posteriorLinkedTrainContainer.getByTestId(
49+
'linked-train-search-button'
50+
);
51+
}
52+
53+
// Add an anterior and posterior linked path card, verify default fields, and delete it
54+
async addAndDeleteDefaultLinkedPath() {
55+
await this.anteriorAddLinkedPathButton.click();
56+
await expect(this.anteriorLinkedTrainField).toHaveValue('');
57+
await expect(this.anteriorLinkedTrainDate).toHaveValue('16/10/24');
58+
await expect(this.anteriorLinkedTrainSearchButton).toBeVisible();
59+
await this.anteriorDeleteLinkedPathButton.click();
60+
await expect(this.anteriorLinkedTrainField).not.toBeVisible();
61+
await expect(this.anteriorLinkedTrainDate).not.toBeVisible();
62+
await expect(this.anteriorLinkedTrainSearchButton).not.toBeVisible();
63+
await this.posteriorAddLinkedPathButton.click();
64+
await expect(this.posteriorLinkedTrainField).toHaveValue('');
65+
await expect(this.posteriorLinkedTrainDate).toHaveValue('16/10/24');
66+
await expect(this.posteriorLinkedTrainSearchButton).toBeVisible();
67+
await this.posteriorDeleteLinkedPathButton.click();
68+
await expect(this.posteriorLinkedTrainField).not.toBeVisible();
69+
await expect(this.posteriorLinkedTrainDate).not.toBeVisible();
70+
await expect(this.posteriorLinkedTrainSearchButton).not.toBeVisible();
71+
}
72+
}
73+
export default STDCMLinkedTrainPage;

front/tests/pages/stdcm-page-model.ts

+32-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export interface ConsistFields {
3636
}
3737
const EXPECT_TO_PASS_TIMEOUT = 90_000; // Since toPass ignores custom expect timeouts, this timeout is set to account for all actions within the function.
3838
const MINIMUM_SIMULATION_NUMBER = 1;
39+
3940
class STDCMPage {
4041
readonly page: Page;
4142

@@ -65,6 +66,14 @@ class STDCMPage {
6566

6667
readonly addViaButton: Locator;
6768

69+
readonly anteriorLinkedTrainContainer: Locator;
70+
71+
readonly anteriorAddLinkedPathButton: Locator;
72+
73+
readonly posteriorLinkedTrainContainer: Locator;
74+
75+
readonly posteriorAddLinkedPathButton: Locator;
76+
6877
readonly launchSimulationButton: Locator;
6978

7079
readonly originChField: Locator;
@@ -175,6 +184,16 @@ class STDCMPage {
175184
this.speedLimitTagField = page.locator('#speed-limit-by-tag-selector');
176185
this.maxSpeedField = page.locator('#maxSpeed');
177186
this.addViaButton = page.locator('.stdcm-vias-list button .stdcm-card__body.add-via');
187+
this.anteriorLinkedTrainContainer = page.locator(
188+
'.stdcm-linked-train-search-container.anterior-linked-train'
189+
);
190+
this.anteriorAddLinkedPathButton =
191+
this.anteriorLinkedTrainContainer.locator('.add-linked-train');
192+
this.posteriorLinkedTrainContainer = page.locator(
193+
'.stdcm-linked-train-search-container.posterior-linked-train'
194+
);
195+
this.posteriorAddLinkedPathButton =
196+
this.posteriorLinkedTrainContainer.locator('.add-linked-train');
178197
this.launchSimulationButton = page.getByTestId('launch-simulation-button');
179198
this.originChField = this.originCard.locator('[id^="id"][id$="-ch"]');
180199
this.destinationChField = this.destinationCard.locator('[id^="id"][id$="-ch"]');
@@ -299,6 +318,8 @@ class STDCMPage {
299318
this.consistCard,
300319
this.originCard,
301320
this.addViaButton,
321+
this.anteriorAddLinkedPathButton,
322+
this.posteriorAddLinkedPathButton,
302323
this.destinationCard,
303324
this.mapContainer,
304325
this.launchSimulationButton,
@@ -309,7 +330,7 @@ class STDCMPage {
309330
}
310331

311332
// Verify all input fields are empty
312-
async verifyAllFieldsEmpty() {
333+
async verifyAllDefaultPageFields() {
313334
const emptyFields = [
314335
this.tractionEngineField,
315336
this.towedRollingStockField,
@@ -321,20 +342,28 @@ class STDCMPage {
321342
this.originChField,
322343
this.destinationChField,
323344
];
345+
const { arrivalDate, arrivalTime, tolerance, speedLimitTag } = DEFAULT_DETAILS;
324346
for (const field of emptyFields) await expect(field).toHaveValue('');
325-
await expect(this.speedLimitTagField).toHaveValue('__PLACEHOLDER__');
347+
await expect(this.originArrival).toHaveValue(ORIGIN_DETAILS.arrivalType.default);
348+
await expect(this.destinationArrival).toHaveValue(DESTINATION_DETAILS.arrivalType.default);
349+
await expect(this.speedLimitTagField).toHaveValue(speedLimitTag);
350+
await expect(this.dateOriginArrival).toHaveValue(arrivalDate);
351+
await expect(this.timeOriginArrival).toHaveValue(arrivalTime);
352+
await expect(this.toleranceOriginArrival).toHaveValue(tolerance);
326353
}
327354

328355
// Add a via card, verify fields, and delete it
329-
async addAndDeleteEmptyVia() {
356+
async addAndDeletedDefaultVia() {
330357
await this.addViaButton.click();
331358
await expect(this.getViaCI(1)).toHaveValue('');
332359
await expect(this.getViaCH(1)).toHaveValue('');
360+
await expect(this.getViaType(1)).toHaveValue(VIA_STOP_TYPES.PASSAGE_TIME);
333361
await this.viaIcon.hover();
334362
await expect(this.viaDeleteButton).toBeVisible();
335363
await this.viaDeleteButton.click();
336364
await expect(this.getViaCI(1)).not.toBeVisible();
337365
await expect(this.getViaCH(1)).not.toBeVisible();
366+
await expect(this.getViaType(1)).not.toBeVisible();
338367
}
339368

340369
// Verify the origin suggestions when searching for north

front/tests/utils/simulationSheet.ts

+124-10
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,143 @@ import path from 'path';
33

44
import { expect } from '@playwright/test';
55

6-
import type { Simulation } from './types';
6+
export interface Simulation {
7+
header: {
8+
toolDescription: string;
9+
documentTitle: string;
10+
};
11+
applicationDate: string;
12+
applicationDateValue: string;
13+
trainDetails: {
14+
compositionCode: string;
15+
compositionCodeValue: string;
16+
towedMaterial: string;
17+
towedMaterialValue: string;
18+
maxSpeed: string;
19+
maxSpeedValue: string;
20+
maxTonnage: string;
21+
maxTonnageValue: string;
22+
referenceEngine: string;
23+
referenceEngineValue: string;
24+
maxLength: string;
25+
maxLengthValue: string;
26+
};
27+
requestedRoute: {
28+
station1: {
29+
name: string;
30+
ch: string;
31+
arrivalTime?: string | null;
32+
plusTolerance?: string | null;
33+
minusTolerance?: string | null;
34+
stop?: string | null;
35+
departureTime?: string | null;
36+
reason: string;
37+
};
38+
station2: {
39+
name: string;
40+
ch: string;
41+
arrivalTime?: string | null;
42+
plusTolerance?: string | null;
43+
minusTolerance?: string | null;
44+
stop?: string | null;
45+
departureTime?: string | null;
46+
reason: string;
47+
};
48+
station3: {
49+
name: string;
50+
ch: string;
51+
arrivalTime?: string | null;
52+
plusTolerance?: string | null;
53+
minusTolerance?: string | null;
54+
stop?: string | null;
55+
departureTime?: string | null;
56+
reason: string;
57+
};
58+
};
59+
simulationDetails: {
60+
totalDistance: string;
61+
simulationRoute: {
62+
station1: {
63+
name: string;
64+
ch: string;
65+
track: string;
66+
arrivalTime?: string | null;
67+
passageTime?: string | null;
68+
departureTime?: string | null;
69+
tonnage: string;
70+
length: string;
71+
referenceEngine?: string | null;
72+
stopType?: string | null;
73+
};
74+
station2: {
75+
name: string;
76+
ch: string;
77+
track: string;
78+
arrivalTime?: string | null;
79+
passageTime?: string | null;
80+
departureTime?: string | null;
81+
tonnage: string;
82+
length: string;
83+
referenceEngine?: string | null;
84+
stopType?: string | null;
85+
};
86+
station3: {
87+
name: string;
88+
ch: string;
89+
track: string;
90+
arrivalTime?: string | null;
91+
passageTime?: string | null;
92+
departureTime?: string | null;
93+
tonnage: string;
94+
length: string;
95+
referenceEngine?: string | null;
96+
stopType?: string | null;
97+
};
98+
station4: {
99+
name: string;
100+
ch: string;
101+
track: string;
102+
arrivalTime?: string | null;
103+
passageTime?: string | null;
104+
departureTime?: string | null;
105+
tonnage: string;
106+
length: string;
107+
referenceEngine?: string | null;
108+
stopType?: string | null;
109+
};
110+
station5: {
111+
name: string;
112+
ch: string;
113+
track: string;
114+
arrivalTime?: string | null;
115+
passageTime?: string | null;
116+
departureTime?: string | null;
117+
tonnage: string;
118+
length: string;
119+
referenceEngine?: string | null;
120+
stopType?: string | null;
121+
};
122+
};
123+
disclaimer: string;
124+
};
125+
}
7126

8127
/**
9-
* Find the first PDF file in a directory.
128+
* Finds the first PDF file in a directory.
10129
* @param directory - The directory to search in.
11130
* @returns The absolute path to the PDF file, or `null` if no PDF file is found.
12131
*/
13132
export function findFirstPdf(directory: string): string | null {
14133
try {
15134
const pdfFile = fs.readdirSync(directory).find((file) => file.endsWith('.pdf'));
16-
if (!pdfFile) {
17-
console.error(`No PDF files found in directory: ${directory}`);
18-
return null;
19-
}
20-
return path.resolve(directory, pdfFile);
21-
} catch (error) {
22-
console.error(`Error reading directory: ${directory}`, error);
135+
return pdfFile ? path.resolve(directory, pdfFile) : null;
136+
} catch {
23137
return null;
24138
}
25139
}
26140

27141
/**
28-
* Verify the PDF content against the expected simulation.
142+
* Verifies the PDF content against the expected simulation.
29143
* @param pdfText The text extracted from the PDF.
30144
* @param expectedSimulation The expected simulation data.
31145
*/

0 commit comments

Comments
 (0)