Skip to content

Commit

Permalink
front: add e2e tests for paced train filter
Browse files Browse the repository at this point in the history
Signed-off-by: SharglutDev <[email protected]>
  • Loading branch information
SharglutDev committed Mar 3, 2025
1 parent 9173d49 commit d362ec8
Show file tree
Hide file tree
Showing 5 changed files with 386 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const FilterPanel = ({ toggleFilterPanel, timetableFilters }: FilterPanelProps)
<Select
getOptionLabel={(option) => option.label}
getOptionValue={(option) => option.value}
id="train-validity"
id="timetable-train-validity-filter"
label={t('timetable.validityFilter')}
narrow
small
Expand All @@ -112,7 +112,7 @@ const FilterPanel = ({ toggleFilterPanel, timetableFilters }: FilterPanelProps)
<Select
getOptionLabel={(option) => option.label}
getOptionValue={(option) => option.value}
id="train-type"
id="timetable-train-type-filter"
label={t('timetable.trainType')}
narrow
small
Expand Down Expand Up @@ -146,7 +146,7 @@ const FilterPanel = ({ toggleFilterPanel, timetableFilters }: FilterPanelProps)
<Select
getOptionLabel={(option) => option.label}
getOptionValue={(option) => option.value}
id="train-keep-timetable"
id="timetable-train-punctuality-filter"
label={t('timetable.punctuality')}
narrow
small
Expand All @@ -165,8 +165,8 @@ const FilterPanel = ({ toggleFilterPanel, timetableFilters }: FilterPanelProps)
</div>
</div>
<div className="compositions-code">
<label htmlFor="composition-tag-filter">{t('timetable.compositionCodes')}</label>
<div className="composition-tag-filter" id="composition-tag-filter">
<label htmlFor="timetable-composition-tag-filter">{t('timetable.compositionCodes')}</label>
<div className="composition-tag-filter" id="timetable-composition-tag-filter">
{uniqueTags.map((tag) => {
const displayTag = tag !== 'NO CODE' ? tag : t('timetable.noSpeedLimitTagsShort');
return (
Expand Down
26 changes: 26 additions & 0 deletions front/src/modules/trainschedule/components/Timetable/Timetable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,37 @@ const Timetable = ({
{
...trainSchedulesWithDetails[0],
id: formatEditoastTrainIdToPacedTrainId(12345),
trainName: 'Paced train 1',
labels: ['Tag-1'],
paced: {
duration: Duration.parse('PT2H'),
step: Duration.parse('PT30M'),
},
},
{
...trainSchedulesWithDetails[0],
id: formatEditoastTrainIdToPacedTrainId(123456),
trainName: 'Paced train 2',
invalidReason: 'rolling_stock_not_found',
isValid: false,
scheduledPointsNotHonored: false,
paced: {
duration: Duration.parse('PT1H'),
step: Duration.parse('PT10M'),
},
},
{
...trainSchedulesWithDetails[0],
id: formatEditoastTrainIdToPacedTrainId(1234567),
trainName: 'Paced train 3',
notHonoredReason: 'scheduleNotHonored',
isValid: true,
scheduledPointsNotHonored: true,
paced: {
duration: Duration.parse('PT2H'),
step: Duration.parse('PT5M'),
},
},
]
: trainSchedulesWithDetails
);
Expand Down
194 changes: 182 additions & 12 deletions front/tests/008-train-schedule.spec.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,66 @@
import type { Scenario, Project, Study, Infra } from 'common/api/osrdEditoastApi';
import type {
Scenario,
Project,
Study,
Infra,
TrainScheduleBase,
} from 'common/api/osrdEditoastApi';

import {
trainScheduleProjectName,
trainScheduleScenarioName,
trainScheduleStudyName,
} from './assets/constants/project-const';
import test from './logging-fixture';
import OperationalStudiesPage from './pages/operational-studies/operational-studies-page';
import ScenarioTimetableSection from './pages/operational-studies/scenario-timetable-section';
import { waitForInfraStateToBeCached } from './utils';
import { getTranslations, waitForInfraStateToBeCached } from './utils';
import { getInfra, getProject, getScenario, getStudy } from './utils/api-utils';
import readJsonFile from './utils/file-utils';
import type { TimetableFilterTranslations } from './utils/types';

const enTranslations: TimetableFilterTranslations = readJsonFile(
'public/locales/en/operationalStudies/scenario.json'
);
const frTranslations: TimetableFilterTranslations = readJsonFile(
'public/locales/fr/operationalStudies/scenario.json'
);

test.describe('Verify train schedule elements and filters', () => {
test.slow();
test.use({ viewport: { width: 1920, height: 1080 } });

let scenarioTimetableSection: ScenarioTimetableSection;
let operationalStudiesPage: OperationalStudiesPage;

let project: Project;
let study: Study;
let scenario: Scenario;
let infra: Infra;
let translations: TimetableFilterTranslations;

// Constants for expected train counts
const TOTAL_TRAINS = 21;
// TODO Paced train - update these constant in https://github.com/OpenRailAssociation/osrd/issues/10615
// While the back end for paced trains isn't ready, 3 paced trains are hardcoded and
// added to the list of train schedules for testing purposes.
// These 3 paced trains are copy of the first train schedule in the list.
const TOTAL_PACED_TRAINS = 3;
const TOTAL_ITEMS = TOTAL_TRAINS + TOTAL_PACED_TRAINS;
const VALID_PACED_TRAINS = 1;
const INVALID_PACED_TRAINS = 1;
const NOT_HONORED_PACED_TRAINS = 1;
const NAME_FILTERED_ITEMS = 1;
const LABEL_FILTERED_ITEMS = 1;
const ROLLING_STOCK_FILTERED_ITEMS = 5 + TOTAL_PACED_TRAINS;
const VALID_TRAINS = 17;
const VALID_ITEMS = 17 + VALID_PACED_TRAINS;
const INVALID_TRAINS = 4;
const INVALID_ITEMS = 4 + INVALID_PACED_TRAINS;
const HONORED_TRAINS = 14;
const HONORED_ITEMS = HONORED_TRAINS + VALID_PACED_TRAINS;
const NOT_HONORED_TRAINS = 3;
const NOT_HONORED_ITEMS = NOT_HONORED_TRAINS + NOT_HONORED_PACED_TRAINS;
const VALID_AND_HONORED_TRAINS = 14;
const INVALID_AND_NOT_HONORED_TRAINS = 0;

Expand All @@ -35,10 +69,15 @@ test.describe('Verify train schedule elements and filters', () => {
study = await getStudy(project.id, trainScheduleStudyName);
scenario = await getScenario(project.id, study.id, trainScheduleScenarioName);
infra = await getInfra();
translations = getTranslations({
en: enTranslations,
fr: frTranslations,
});
});

test.beforeEach('Navigate to scenario page before each test', async ({ page }) => {
scenarioTimetableSection = new ScenarioTimetableSection(page);
operationalStudiesPage = new OperationalStudiesPage(page);
await page.goto(
`/operational-studies/projects/${project.id}/studies/${study.id}/scenarios/${scenario.id}`
);
Expand All @@ -52,31 +91,59 @@ test.describe('Verify train schedule elements and filters', () => {
await scenarioTimetableSection.verifyTrainCount(TOTAL_TRAINS);
await scenarioTimetableSection.verifyInvalidTrainsMessageVisibility();
await scenarioTimetableSection.checkSelectedTimetableTrain();
await scenarioTimetableSection.filterValidityAndVerifyTrainCount('Valid', VALID_TRAINS);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'Valid',
VALID_TRAINS,
translations
);
await scenarioTimetableSection.verifyEachTrainSimulation();
});

// TODO Paced train - remove this test in https://github.com/OpenRailAssociation/osrd/issues/10791
/** *************** Test 2 **************** */
test('Filtering imported trains', async () => {
// Verify train count and apply different filters for validity and honored status
await scenarioTimetableSection.verifyTrainCount(TOTAL_TRAINS);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount('Invalid', INVALID_TRAINS);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount('All', TOTAL_TRAINS);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount('Honored', HONORED_TRAINS);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'Invalid',
INVALID_TRAINS,
translations
);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'All',
TOTAL_TRAINS,
translations
);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount(
'Honored',
HONORED_TRAINS,
translations
);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'Valid',
VALID_AND_HONORED_TRAINS
VALID_AND_HONORED_TRAINS,
translations
);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount(
'Not honored',
NOT_HONORED_TRAINS
NOT_HONORED_TRAINS,
translations
);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'Invalid',
INVALID_AND_NOT_HONORED_TRAINS
INVALID_AND_NOT_HONORED_TRAINS,
translations
);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount(
'All',
INVALID_TRAINS,
translations
);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'All',
TOTAL_TRAINS,
translations
);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount('All', INVALID_TRAINS);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount('All', TOTAL_TRAINS);

// Verify train composition filters with predefined filter codes and expected counts
const compositionFilters = [
Expand All @@ -87,7 +154,110 @@ test.describe('Verify train schedule elements and filters', () => {
];

for (const filter of compositionFilters) {
await scenarioTimetableSection.clickCodeCompoTrainFilterButton(filter.code, filter.count);
await scenarioTimetableSection.filterCompoCodeAndVerifyTrainCount(
filter.code,
filter.count,
translations
);
}
});

// TODO Paced train : update this test with real data in https://github.com/OpenRailAssociation/osrd/issues/10615
/** *************** Test 3 **************** */
test('Filtering imported trains and paced trains', async () => {
// Verify train count and apply different filters for validity and honored status

await operationalStudiesPage.checkPacedTrainSwitch();

// While the back end for paced trains isn't ready, 3 paced trains are hardcoded and
// added to the list of train schedules for testing purposes.
// These 3 paced trains are copy of the first train schedule in the list.
await scenarioTimetableSection.verifyTrainCount(
TOTAL_TRAINS + VALID_PACED_TRAINS + INVALID_PACED_TRAINS + NOT_HONORED_PACED_TRAINS
);

await scenarioTimetableSection.checkTimetableFilterVisibilityLabelDefaultValue(
translations.timetable,
{ inputDefaultValue: '', selectDefaultValue: 'both' }
);

const trainSchedulesJson: TrainScheduleBase[] = readJsonFile(
'./tests/assets/train-schedule/train_schedules.json'
);
const firstTrainSchedule = trainSchedulesJson.at(0);

// REMPLACER COUNT PAR CHECK DES X MISSIONS, X TRAINS

// Name and label filter
await scenarioTimetableSection.filterNameAndVerifyTrainCount(
'Paced Train 1',
NAME_FILTERED_ITEMS,
''
);
const firstItemLabel = firstTrainSchedule!.labels![0];
await scenarioTimetableSection.filterNameAndVerifyTrainCount(
firstItemLabel,
LABEL_FILTERED_ITEMS,
''
);

// Rolling stock name and details filter
const firstItemRollingStock = firstTrainSchedule!.rolling_stock_name;
await scenarioTimetableSection.filterRollingStockAndVerifyTrainCount(
firstItemRollingStock,
ROLLING_STOCK_FILTERED_ITEMS,
''
);

// Validity filter
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'Invalid',
INVALID_ITEMS,
translations
);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'Valid',
VALID_ITEMS,
translations
);

// Punctuality filter
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount(
'Honored',
HONORED_ITEMS,
translations
);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount(
'Not honored',
NOT_HONORED_ITEMS,
translations
);

// Train type filter
await scenarioTimetableSection.filterTrainTypeAndVerifyTrainCount(
'Service',
NOT_HONORED_PACED_TRAINS
);
await scenarioTimetableSection.filterHonoredAndVerifyTrainCount(
'All',
VALID_PACED_TRAINS + NOT_HONORED_PACED_TRAINS,
translations
);
await scenarioTimetableSection.filterValidityAndVerifyTrainCount(
'All',
TOTAL_PACED_TRAINS,
translations
);

await scenarioTimetableSection.filterTrainTypeAndVerifyTrainCount('Unique train', TOTAL_TRAINS);
await scenarioTimetableSection.filterTrainTypeAndVerifyTrainCount('All', TOTAL_ITEMS);

// Verify train composition filters with predefined filter codes and expected counts
// TODO Paced train : add a paced train with a unique compo code in https://github.com/OpenRailAssociation/osrd/issues/10615
await scenarioTimetableSection.filterCompoCodeAndVerifyTrainCount(
null,
10 + TOTAL_PACED_TRAINS,
translations
);
});
});
Loading

0 comments on commit d362ec8

Please sign in to comment.