-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
front: add times and stops e2e test for operational studies
Signed-off-by: maymanaf <med.aymen.naf@gmail.com>
- Loading branch information
Showing
15 changed files
with
801 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
import { test, expect } from '@playwright/test'; | ||
|
||
import type { Project, Scenario, Study } from 'common/api/osrdEditoastApi'; | ||
|
||
import HomePage from './pages/home-page-model'; | ||
import OperationalStudiesInputTablePage from './pages/op-input-table-page-model'; | ||
import OperationalStudiesOutputTablePage from './pages/op-output-table-page-model'; | ||
import OperationalStudiesTimetablePage from './pages/op-timetable-page-model'; | ||
import OperationalStudiesPage from './pages/operational-studies-page-model'; | ||
import ScenarioPage from './pages/scenario-page-model'; | ||
import { readJsonFile, safeClick } from './utils'; | ||
import { cleanWhitespace, cleanWhitespaces, type StationData } from './utils/dataNormalizer'; | ||
import setupScenario from './utils/scenario'; | ||
import scrollContainer from './utils/scrollHelper'; | ||
import enTranslations from '../public/locales/en/timesStops.json'; | ||
import frTranslations from '../public/locales/fr/timesStops.json'; | ||
|
||
let project: Project; | ||
let study: Study; | ||
let scenario: Scenario; | ||
let selectedLanguage: string; | ||
|
||
const dualRollingStockName = 'dual-mode_rollingstock_test_e2e'; | ||
|
||
const initialInputsData: CellData[] = readJsonFile( | ||
'./tests/assets/operationStudies/timesAndStops/initialInputs.json' | ||
); | ||
const updatedInputsData: CellData[] = readJsonFile( | ||
'./tests/assets/operationStudies/timesAndStops/updatedInputs.json' | ||
); | ||
const outputExpectedCellData: StationData[] = readJsonFile( | ||
'./tests/assets/operationStudies/timesAndStops/expectedOutputsCellsData.json' | ||
); | ||
const inputExpectedData = readJsonFile( | ||
'./tests/assets/operationStudies/timesAndStops/expectedInputsCellsData.json' | ||
); | ||
const updatedCellData = readJsonFile( | ||
'./tests/assets/operationStudies/timesAndStops/updatedInputsCellsData.json' | ||
); | ||
|
||
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' }, | ||
]; | ||
|
||
type TranslationKeys = keyof typeof enTranslations; | ||
|
||
// Define CellData interface for table cell data | ||
interface CellData { | ||
stationName: string; | ||
header: TranslationKeys; | ||
value: string; | ||
marginForm?: string; | ||
} | ||
|
||
test.beforeEach(async ({ page }) => { | ||
// Create a new scenario | ||
({ project, study, scenario } = await setupScenario()); | ||
|
||
// Navigate to home page and retrieve the language setting | ||
const homePage = new HomePage(page); | ||
await homePage.goToHomePage(); | ||
selectedLanguage = await homePage.getOSRDLanguage(); | ||
|
||
// Go to the specific operational study scenario page | ||
await page.goto( | ||
`/operational-studies/projects/${project.id}/studies/${study.id}/scenarios/${scenario.id}` | ||
); | ||
}); | ||
|
||
test.describe('Times and Stops Tab Verification', () => { | ||
// Set viewport to avoid scrolling issues and ensure elements are attached to the DOM | ||
test.use({ viewport: { width: 1920, height: 1080 } }); | ||
|
||
test('should correctly set and display times and stops tables', async ({ page }) => { | ||
// Page models | ||
const [ | ||
opInputTablePage, | ||
opTimetablePage, | ||
opOutputTablePage, | ||
operationalStudiesPage, | ||
scenarioPage, | ||
] = [ | ||
new OperationalStudiesInputTablePage(page), | ||
new OperationalStudiesTimetablePage(page), | ||
new OperationalStudiesOutputTablePage(page), | ||
new OperationalStudiesPage(page), | ||
new ScenarioPage(page), | ||
]; | ||
|
||
// Setup the initial train configuration and schedule | ||
await scenarioPage.checkInfraLoaded(); | ||
await operationalStudiesPage.clickOnAddTrainBtn(); | ||
await scenarioPage.setTrainScheduleName('Train-name-e2e-test'); | ||
await page.waitForTimeout(500); | ||
await operationalStudiesPage.setTrainStartTime('11:22:40'); | ||
await operationalStudiesPage.selectRollingStock(dualRollingStockName); | ||
|
||
// Perform pathfinding | ||
await scenarioPage.openTabByDataId('tab-pathfinding'); | ||
await operationalStudiesPage.performPathfindingByTrigram('WS', 'NES'); | ||
|
||
// Navigate to the Times and Stops tab and scroll into view | ||
await scenarioPage.openTabByDataId('tab-timesStops'); | ||
await scrollContainer(page, '.time-stops-datasheet .dsg-container'); | ||
|
||
// Set column names based on the selected language | ||
const translations = selectedLanguage === 'English' ? enTranslations : frTranslations; | ||
const expectedColumnNames = cleanWhitespaces([ | ||
translations.name, | ||
'Ch', | ||
translations.arrivalTime, | ||
translations.departureTime, | ||
translations.stopTime, | ||
translations.receptionOnClosedSignal, | ||
translations.theoreticalMargin, | ||
]); | ||
|
||
// Verify that the actual column headers match the expected headers | ||
const actualColumnHeaders = cleanWhitespaces( | ||
await opInputTablePage.columnHeaders.allInnerTexts() | ||
); | ||
expect(actualColumnHeaders).toEqual(expectedColumnNames); | ||
|
||
// Validate the initial active row count | ||
await opInputTablePage.verifyActiveRowsCount(2); | ||
|
||
// Fill in table cells based on the predefined cell data | ||
for (const cell of initialInputsData) { | ||
const translatedHeader = cleanWhitespace(translations[cell.header]); | ||
await opInputTablePage.fillTableCellByStationAndHeader( | ||
cell.stationName, | ||
translatedHeader, | ||
cell.value, | ||
selectedLanguage, | ||
cell.marginForm | ||
); | ||
} | ||
|
||
// Verify the table after modification | ||
await opInputTablePage.verifyActiveRowsCount(4); | ||
await opInputTablePage.verifyDeleteButtons(2); | ||
await opInputTablePage.verifyInputTableData(inputExpectedData); | ||
|
||
// Switch to Pathfinding tab and validate waypoints | ||
await scenarioPage.openTabByDataId('tab-pathfinding'); | ||
for (const [viaIndex, expectedValue] of expectedViaValues.entries()) { | ||
const droppedWaypoint = operationalStudiesPage.droppedWaypoints.nth(viaIndex); | ||
await OperationalStudiesPage.validateAddedWaypoint( | ||
droppedWaypoint, | ||
expectedValue.name, | ||
expectedValue.ch, | ||
expectedValue.uic | ||
); | ||
} | ||
|
||
// Add the train schedule and verify simulation results | ||
await scenarioPage.addTrainSchedule(); | ||
await scenarioPage.returnSimulationResult(); | ||
opTimetablePage.verifyTimeStopsDatasheetVisibility(); | ||
// Scroll and extract data from output table | ||
await scrollContainer(page, '.osrd-simulation-container .time-stops-datasheet .dsg-container'); | ||
await opOutputTablePage.getOutputTableData(outputExpectedCellData, selectedLanguage); | ||
}); | ||
|
||
test('should correctly update and clear input table row', async ({ page }) => { | ||
// Page models | ||
const [opInputTablePage, operationalStudiesPage, scenarioPage] = [ | ||
new OperationalStudiesInputTablePage(page), | ||
new OperationalStudiesPage(page), | ||
new ScenarioPage(page), | ||
]; | ||
|
||
// Setup initial train configuration | ||
await scenarioPage.checkInfraLoaded(); | ||
await operationalStudiesPage.clickOnAddTrainBtn(); | ||
await scenarioPage.setTrainScheduleName('Train-name-e2e-test'); | ||
await page.waitForTimeout(500); | ||
await operationalStudiesPage.setTrainStartTime('11:22:40'); | ||
await operationalStudiesPage.selectRollingStock(dualRollingStockName); | ||
|
||
// Perform pathfinding and navigate to Times and Stops tab | ||
await scenarioPage.openTabByDataId('tab-pathfinding'); | ||
await operationalStudiesPage.performPathfindingByTrigram('WS', 'NES'); | ||
await scenarioPage.openTabByDataId('tab-timesStops'); | ||
await scrollContainer(page, '.time-stops-datasheet .dsg-container'); | ||
|
||
const translations = selectedLanguage === 'English' ? enTranslations : frTranslations; | ||
// Fill in table cells based on the predefined cell data | ||
for (const cell of initialInputsData) { | ||
const translatedHeader = cleanWhitespace(translations[cell.header]); | ||
await opInputTablePage.fillTableCellByStationAndHeader( | ||
cell.stationName, | ||
translatedHeader, | ||
cell.value, | ||
selectedLanguage, | ||
cell.marginForm | ||
); | ||
} | ||
await opInputTablePage.verifyInputTableData(inputExpectedData); | ||
|
||
// Update table inputs | ||
await opInputTablePage.verifyActiveRowsCount(4); | ||
for (const cell of updatedInputsData) { | ||
const translatedHeader = cleanWhitespace(translations[cell.header]); | ||
await opInputTablePage.fillTableCellByStationAndHeader( | ||
cell.stationName, | ||
translatedHeader, | ||
cell.value, | ||
selectedLanguage, | ||
cell.marginForm | ||
); | ||
} | ||
|
||
// Delete a row and validate row count | ||
await opInputTablePage.verifyDeleteButtons(2); | ||
await safeClick(opInputTablePage.deleteButtons.nth(0)); | ||
await opInputTablePage.verifyActiveRowsCount(4); | ||
await opInputTablePage.verifyDeleteButtons(1); | ||
await opInputTablePage.verifyInputTableData(updatedCellData); | ||
|
||
// Switch to Pathfinding tab and validate waypoints | ||
await scenarioPage.openTabByDataId('tab-pathfinding'); | ||
for (const [viaIndex, expectedValue] of expectedViaValues.entries()) { | ||
const droppedWaypoint = operationalStudiesPage.droppedWaypoints.nth(viaIndex); | ||
await OperationalStudiesPage.validateAddedWaypoint( | ||
droppedWaypoint, | ||
expectedValue.name, | ||
expectedValue.ch, | ||
expectedValue.uic | ||
); | ||
} | ||
}); | ||
}); |
18 changes: 18 additions & 0 deletions
18
front/tests/assets/operationStudies/timesAndStops/expectedInputsCellsData.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[ | ||
{ | ||
"row": 1, | ||
"values": ["West_station", "BV", "11:22:40", "", "", "5%"] | ||
}, | ||
{ | ||
"row": 2, | ||
"values": ["Mid_West_station", "BV", "11:30:40", "11:35:40", "300", "1min/100km"] | ||
}, | ||
{ | ||
"row": 3, | ||
"values": ["Mid_East_station", "BV", "11:45:21", "11:47:25", "124", ""] | ||
}, | ||
{ | ||
"row": 4, | ||
"values": ["North_East_station", "BV", "", "", "0", ""] | ||
} | ||
] |
66 changes: 66 additions & 0 deletions
66
front/tests/assets/operationStudies/timesAndStops/expectedOutputsCellsData.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
[ | ||
{ | ||
"stationName": "West_station", | ||
"stationCh": "BV", | ||
"requestedArrival": "11:22:40", | ||
"requestedDeparture": "", | ||
"stopTime": "", | ||
"signalReceptionClosed": false, | ||
"margin": { | ||
"theoretical": "5 %", | ||
"theoreticalS": "23 s", | ||
"actual": "23 s", | ||
"difference": "0 s" | ||
}, | ||
"calculatedArrival": "11:22:40", | ||
"calculatedDeparture": "" | ||
}, | ||
{ | ||
"stationName": "Mid_West_station", | ||
"stationCh": "BV", | ||
"requestedArrival": "11:30:40", | ||
"requestedDeparture": "11:35:40", | ||
"stopTime": "300", | ||
"signalReceptionClosed": true, | ||
"margin": { | ||
"theoretical": "1 min/100km", | ||
"theoreticalS": "9 s", | ||
"actual": "167 s", | ||
"difference": "159 s" | ||
}, | ||
"calculatedArrival": "11:30:39", | ||
"calculatedDeparture": "11:35:39" | ||
}, | ||
{ | ||
"stationName": "Mid_East_station", | ||
"stationCh": "BV", | ||
"requestedArrival": "11:45:21", | ||
"requestedDeparture": "11:47:25", | ||
"stopTime": "124", | ||
"signalReceptionClosed": false, | ||
"margin": { | ||
"theoretical": "", | ||
"theoreticalS": "12 s", | ||
"actual": "12 s", | ||
"difference": "0 s" | ||
}, | ||
"calculatedArrival": "11:45:20", | ||
"calculatedDeparture": "11:47:24" | ||
}, | ||
{ | ||
"stationName": "North_East_station", | ||
"stationCh": "BV", | ||
"requestedArrival": "", | ||
"requestedDeparture": "", | ||
"stopTime": "0", | ||
"signalReceptionClosed": false, | ||
"margin": { | ||
"theoretical": "", | ||
"theoreticalS": "", | ||
"actual": "", | ||
"difference": "" | ||
}, | ||
"calculatedArrival": "11:56:23", | ||
"calculatedDeparture": "" | ||
} | ||
] |
34 changes: 34 additions & 0 deletions
34
front/tests/assets/operationStudies/timesAndStops/initialInputs.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[ | ||
{ | ||
"stationName": "West_station", | ||
"header": "theoreticalMargin", | ||
"value": "5%", | ||
"marginForm": "% ou min/100km" | ||
}, | ||
{ | ||
"stationName": "Mid_West_station", | ||
"header": "theoreticalMargin", | ||
"value": "1min/100km", | ||
"marginForm": "% ou min/100km" | ||
}, | ||
{ | ||
"stationName": "Mid_West_station", | ||
"header": "arrivalTime", | ||
"value": "11:30:40" | ||
}, | ||
{ | ||
"stationName": "Mid_West_station", | ||
"header": "stopTime", | ||
"value": "300" | ||
}, | ||
{ | ||
"stationName": "Mid_East_station", | ||
"header": "arrivalTime", | ||
"value": "11:45:21" | ||
}, | ||
{ | ||
"stationName": "Mid_East_station", | ||
"header": "stopTime", | ||
"value": "124" | ||
} | ||
] |
18 changes: 18 additions & 0 deletions
18
front/tests/assets/operationStudies/timesAndStops/updatedInputs.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[ | ||
{ | ||
"stationName": "West_station", | ||
"header": "theoreticalMargin", | ||
"value": "3%", | ||
"marginForm": "% ou min/100km" | ||
}, | ||
{ | ||
"stationName": "Mid_East_station", | ||
"header": "arrivalTime", | ||
"value": "12:58:19" | ||
}, | ||
{ | ||
"stationName": "Mid_East_station", | ||
"header": "stopTime", | ||
"value": "21" | ||
} | ||
] |
Oops, something went wrong.