Skip to content

Commit

Permalink
front: add route e2e test for operational studies
Browse files Browse the repository at this point in the history
  • Loading branch information
Maymanaf committed Jul 25, 2024
1 parent ea0f6c9 commit b1862de
Show file tree
Hide file tree
Showing 13 changed files with 575 additions and 42 deletions.
2 changes: 1 addition & 1 deletion front/src/common/BootstrapSNCF/NavBarSNCF.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const LegacyNavBarSNCF = ({ appName, logo = getLogo() }: Props) => {
<span className="mr-2">
{i18n.language && getUnicodeFlagIcon(language2flag(i18n.language))}
</span>
{t(`language.${i18n.language}`)}
<span data-testid="language-info">{t(`language.${i18n.language}`)} </span>
</button>,
<button
data-testid="user-settings-btn"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const DestinationV2 = ({ zoomToFeaturePoint }: DestinationProps) => {
<span className="text-warning mr-2">
<IoFlag />
</span>
{t('noDestinationChosen')}
<span data-testid="no-destination-chosen-text">{t('noDestinationChosen')}</span>
</>
);

Expand All @@ -42,13 +42,14 @@ const DestinationV2 = ({ zoomToFeaturePoint }: DestinationProps) => {
tabIndex={0}
className="flex-grow-1"
>
<strong className="mr-1 text-nowrap">
<strong data-testid="destination-op-info" className="mr-1 text-nowrap">
{/* If destination doesn't have name, we know that it has been added by click on map and has a track property */}
{destination?.name ||
(destination && 'track' in destination && destination.track.split('-')[0])}
</strong>
</div>
<button
data-testid="delete-destination-button"
className="btn btn-sm btn-only-icon btn-white ml-auto"
type="button"
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const OriginV2 = ({ zoomToFeaturePoint }: OriginProps) => {
role="button"
tabIndex={0}
>
<strong className="mr-1 text-nowrap">
<strong data-testid="origin-op-info" className="mr-1 text-nowrap">
{/* If origin doesn't have name, we know that it has been added by click on map and has a track property */}
{origin?.name || (origin && 'track' in origin && origin.track.split('-')[0])}
</strong>
Expand Down Expand Up @@ -87,7 +87,7 @@ const OriginV2 = ({ zoomToFeaturePoint }: OriginProps) => {
<span className="text-success mr-2">
<RiMapPin2Fill />
</span>
{t('noOriginChosen')}
<span data-testid="no-origin-chosen-text">{t('noOriginChosen')}</span>
</>
);

Expand All @@ -99,6 +99,7 @@ const OriginV2 = ({ zoomToFeaturePoint }: OriginProps) => {
</span>
<span className="flex-grow-1">{originPointName}</span>
<button
data-testid="delete-origin-button"
className="btn btn-sm btn-only-icon btn-white"
type="button"
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const ViasV2 = ({ zoomToFeaturePoint, shouldManageStopDuration }: DisplayViasV2P
>
{(providedDraggable) => (
<div
data-testid="dropped-via-info"
ref={providedDraggable.innerRef}
{...providedDraggable.draggableProps}
{...providedDraggable.dragHandleProps}
Expand All @@ -59,12 +60,14 @@ const ViasV2 = ({ zoomToFeaturePoint, shouldManageStopDuration }: DisplayViasV2P
tabIndex={0}
>
<small className="font-weight-bold text-muted mr-1">{index + 1}</small>
<small className="mr-1 text-nowrap">
<small data-testid="via-dropped-name" className="mr-1 text-nowrap">
{`${via.name || `KM ${via.positionOnPath && (Math.round(via.positionOnPath) / 1000000).toFixed(3)}`}`}
</small>
{via.ch && <small>{via.ch}</small>}
{via.ch && <small data-testid="via-dropped-ch">{via.ch}</small>}
{'uic' in via && (
<small className="text-muted ml-3">{formatUicToCi(via.uic)}</small>
<small data-testid="via-dropped-uic" className="text-muted ml-3">
{formatUicToCi(via.uic)}
</small>
)}
</div>
{shouldManageStopDuration && (
Expand All @@ -75,6 +78,7 @@ const ViasV2 = ({ zoomToFeaturePoint, shouldManageStopDuration }: DisplayViasV2P
/>
)}
<button
data-testid="delete-via-button"
className="btn btn-sm btn-only-icon btn-white ml-auto"
type="button"
onClick={() => dispatch(deleteViaV2(index))}
Expand Down
13 changes: 11 additions & 2 deletions front/src/modules/pathfinding/components/Itinerary/ItineraryV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const ItineraryV2 = ({
<div className="d-flex flex-row flex-wrap">
{pathProperties && pathProperties.suggestedOperationalPoints && (
<button
data-testid="add-waypoints-button"
className="col my-1 text-white btn bg-info btn-sm"
type="button"
onClick={() =>
Expand All @@ -125,12 +126,18 @@ const ItineraryV2 = ({
<Plus />
</button>
)}
<button className="col ml-1 my-1 btn bg-warning btn-sm" type="button" onClick={inverseOD}>
<button
data-testid="reverse-itinerary-button"
className="col ml-1 my-1 btn bg-warning btn-sm"
type="button"
onClick={inverseOD}
>
<span className="mr-1">{t('inverseOD')}</span>
<ArrowSwitch />
</button>
<Tipped mode="right">
<button
data-testid="delete-itinerary-button"
type="button"
className="ml-1 mt-1 btn-danger btn btn-sm"
aria-label={t('deleteRoute')}
Expand All @@ -152,7 +159,9 @@ const ItineraryV2 = ({
shouldManageStopDuration={shouldManageStopDuration}
/>
) : (
<small className="ml-4">{t('noPlaceChosen')}</small>
<small data-testid="no-waypoint-chosen-text" className="ml-4">
{t('noPlaceChosen')}
</small>
)}
</div>
<DestinationV2 zoomToFeaturePoint={zoomToFeaturePoint} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,14 @@ const ModalSuggestedVias = ({ suggestedVias }: ModalSuggestedViasProps) => {
{op.uic && <small className="suggested-via-uic text-muted">{formatUicToCi(op.uic)}</small>}
<div className="ml-auto">
{op.positionOnPath && (
<small className="mr-2">{`KM ${(Math.round(op.positionOnPath) / 1000000).toFixed(3)}`}</small>
<small
data-testid="suggested-via-distance"
className="mr-2"
>{`KM ${(Math.round(op.positionOnPath) / 1000000).toFixed(3)}`}</small>
)}
{!isInVias ? (
<button
data-testid="suggested-via-add-button"
className="btn btn-sm btn-only-icon"
type="button"
aria-label={t('addVia')}
Expand All @@ -77,6 +81,7 @@ const ModalSuggestedVias = ({ suggestedVias }: ModalSuggestedViasProps) => {
</button>
) : (
<button
data-testid="suggested-via-delete-button"
className="btn btn-sm btn-only-icon"
type="button"
aria-label={t('removeVia')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) =>

{!pathProperties && isPathFindingActive ? (
<div
data-testid="pathfinding-no-state"
className={cx('content pathfinding-none', { 'mt-2': infra && infra.state !== 'CACHED' })}
>
{t('pathfindingNoState')}
Expand All @@ -103,7 +104,7 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) =>
<span className="lead">
<Alert />
</span>
<span className="flex-grow-1">
<span data-testid="missing-params-info" className="flex-grow-1">
{t('pathfindingMissingParams', { missingElements })}
</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion front/tests/006-stdcm-page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ test.describe('STDCM page', () => {
// TODO: DROP STDCMV1: remove this part
const homePage = new HomePage(page);
await homePage.goToHomePage();
await stdcmPage.toggleStdcmV1();
await homePage.toggleStdcmV1();

await stdcmPage.navigateToPage();
await expect(stdcmPage.scenarioExplorerModal).not.toBeVisible();
Expand Down
6 changes: 4 additions & 2 deletions front/tests/007-op-rollingstock-tab.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ test.describe('Verifying that all elements in the rolling stock tab are loaded c
const operationalStudiesPage = new OperationalStudiesPage(page);
const scenarioPage = new ScenarioPage(page);
const rollingStockSelector = new RollingStockSelectorPage(page);

// TODO: DROP TSV1: remove this part
const homePage = new HomePage(page);
await homePage.goToHomePage();
Expand All @@ -65,7 +66,7 @@ test.describe('Verifying that all elements in the rolling stock tab are loaded c
await scenarioPage.checkInfraLoaded();

// Click on add train button
await operationalStudiesPage.clickOnAddScenarioTrainBtn();
await operationalStudiesPage.clickOnAddTrainBtn();

// Verify the presence of warnings in Rolling Stock and Route Tab
await operationalStudiesPage.verifyTabWarningPresence();
Expand Down Expand Up @@ -100,6 +101,7 @@ test.describe('Verifying that all elements in the rolling stock tab are loaded c
const operationalStudiesPage = new OperationalStudiesPage(page);
const scenarioPage = new ScenarioPage(page);
const rollingStockSelector = new RollingStockSelectorPage(page);

// TODO: DROP TSV1: remove this part
const homePage = new HomePage(page);
await homePage.goToHomePage();
Expand All @@ -114,7 +116,7 @@ test.describe('Verifying that all elements in the rolling stock tab are loaded c
await scenarioPage.checkInfraLoaded();

// Click on add train button
await operationalStudiesPage.clickOnAddScenarioTrainBtn();
await operationalStudiesPage.clickOnAddTrainBtn();

// Open Rolling Stock Selector, search for the added train, and select it
await operationalStudiesPage.openEmptyRollingStockSelector();
Expand Down
170 changes: 170 additions & 0 deletions front/tests/010-op-route-tab.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { test } from '@playwright/test';
import { v4 as uuidv4 } from 'uuid';

import type { Infra, Project, Scenario, Study, Timetable } from 'common/api/osrdEditoastApi';

import scenarioData from './assets/operationStudies/scenario.json';
import HomePage from './pages/home-page-model';
import OperationalStudiesPage from './pages/operational-studies-page-model';
import ScenarioPage from './pages/scenario-page-model';
import { getProject, getStudy, postApiRequest, getInfra } from './utils/index';

let smallInfra: Infra;
let project: Project;
let study: Study;
let scenario: Scenario;
let timetable: Timetable;
let selectedLanguage: string;

const electricRollingStockName = 'rollingstock_1500_25000_test_e2e';

test.beforeAll(async () => {
smallInfra = (await getInfra()) as Infra;
project = await getProject();
study = await getStudy(project.id);
});

test.beforeEach(async ({ page }) => {
timetable = await postApiRequest(`/api/v2/timetable/`, {
electrical_profile_set_id: null,
});
scenario = await postApiRequest(`/api/v2/projects/${project.id}/studies/${study.id}/scenarios/`, {
...scenarioData,
name: `${scenarioData.name} ${uuidv4()}`,
study_id: study.id,
infra_id: smallInfra.id,
timetable_id: timetable.id,
});

// Navigate to the home page and set up the required settings
const homePage = new HomePage(page);
await homePage.goToHomePage();
selectedLanguage = await homePage.getOSRDLanguage();
await homePage.toggleTSV2();

// Navigate to the created scenario page
await page.goto(
`/operational-studies/projects/${project.id}/studies/${study.id}/scenarios/${scenario.id}`
);
});

test.describe('Verifying that all elements in the route tab are loaded correctly', () => {
test('should correctly select a route for operational study', async ({ page, browserName }) => {
const operationalStudiesPage = new OperationalStudiesPage(page);
const scenarioPage = new ScenarioPage(page);

// Verify that the infrastructure is correctly loaded
await scenarioPage.checkInfraLoaded();

// Click on add train button
await operationalStudiesPage.clickOnAddTrainBtn();

// Verify the presence of warnings in Rolling Stock and Route Tab
await operationalStudiesPage.verifyTabWarningPresence();

// Select electric rolling stock
await operationalStudiesPage.selectRollingStock(electricRollingStockName);

// Perform pathfinding and verify no selected route
await scenarioPage.openTabByDataId('tab-pathfinding');
await operationalStudiesPage.verifyNoSelectedRoute(selectedLanguage);
await operationalStudiesPage.performPathfindingByTrigram('WS', 'NES', 'MES');

/* Verify map markers in Chromium browser only:
This check is not performed in Firefox because the map does not load correctly in Firefox. */
if (browserName === 'chromium') {
const expectedMapMarkersValues = ['West_station', 'North_East_station', 'Mid_East_station'];
await operationalStudiesPage.verifyMapMarkers(...expectedMapMarkersValues);
}

// Verify absence of tab warning
await operationalStudiesPage.verifyTabWarningAbsence();
});

test('should correctly add waypoints in a route for operational study', async ({
page,
browserName,
}) => {
const operationalStudiesPage = new OperationalStudiesPage(page);
const scenarioPage = new ScenarioPage(page);

// Click on add train button
await operationalStudiesPage.clickOnAddTrainBtn();

// Select electric rolling stock
await operationalStudiesPage.selectRollingStock(electricRollingStockName);

// Perform pathfinding
await scenarioPage.openTabByDataId('tab-pathfinding');
await operationalStudiesPage.performPathfindingByTrigram('WS', 'NES');

// Add new waypoints
const expectedViaValues = [
{ name: 'Mid_West_station', ch: 'BV', uic: '3', km: 'KM 11.850' },
{ name: 'Mid_East_station', ch: 'BV', uic: '4', km: 'KM 26.300' },
];
await operationalStudiesPage.addNewWaypoints(
2,
['Mid_West_station', 'Mid_East_station'],
expectedViaValues
);

/* Verify map markers in Chromium browser:
This check is not performed in Firefox because the map does not load correctly in Firefox. */
if (browserName === 'chromium') {
const expectedMapMarkersValues = [
'West_station',
'Mid_West_station',
'Mid_East_station',
'North_East_station',
];
await operationalStudiesPage.verifyMapMarkers(...expectedMapMarkersValues);
}

// Verify absence of tab warning
await operationalStudiesPage.verifyTabWarningAbsence();
});

test('should correctly reverse and delete waypoints in a route for operational study', async ({
browserName,
page,
}) => {
const operationalStudiesPage = new OperationalStudiesPage(page);
const scenarioPage = new ScenarioPage(page);

// Click on add train button
await operationalStudiesPage.clickOnAddTrainBtn();

// Select electric rolling stock
await operationalStudiesPage.selectRollingStock(electricRollingStockName);

// Perform pathfinding
await scenarioPage.openTabByDataId('tab-pathfinding');
await operationalStudiesPage.performPathfindingByTrigram('WS', 'SES', 'MWS');
const expectedMapMarkersValues = ['West_station', 'South_East_station', 'Mid_West_station'];
if (browserName === 'chromium') {
await operationalStudiesPage.verifyMapMarkers(...expectedMapMarkersValues);
}

// Reverse the itinerary and verify the map markers
await operationalStudiesPage.clickOnReverseItinerary();
if (browserName === 'chromium') {
const reversedMapMarkersValues = [...expectedMapMarkersValues].reverse();
await operationalStudiesPage.verifyMapMarkers(...reversedMapMarkersValues);
}

// Delete operational points and verify no selected route
await operationalStudiesPage.clickOnDeleteOPButtons(selectedLanguage);
await operationalStudiesPage.verifyNoSelectedRoute(selectedLanguage);

// Search by trigram and verify map markers
await operationalStudiesPage.clickSearchByTrigramSubmitButton();
if (browserName === 'chromium') {
await operationalStudiesPage.verifyMapMarkers(...expectedMapMarkersValues);
}

// Delete itinerary and verify no selected route
await operationalStudiesPage.clickDeleteItineraryButton();
await operationalStudiesPage.verifyNoSelectedRoute(selectedLanguage);
});
});
Loading

0 comments on commit b1862de

Please sign in to comment.