Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

front: handle uncaught exceptions for e2e tests #10004

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const SimulationResults = ({
}

return (
<div className="simulation-results">
<div data-testid="simulation-results" className="simulation-results">
{/* SIMULATION : STICKY BAR */}
{selectedTrainSchedule && (
<div
Expand Down Expand Up @@ -252,7 +252,7 @@ const SimulationResults = ({
)}

{/* SIMULATION : MAP */}
<div className="simulation-map">
<div data-testid="simulation-map" className="simulation-map">
<SimulationResultsMap
geometry={pathProperties?.geometry}
trainSimulation={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const StdcmCard = ({
children,
className = '',
}: StdcmCardProps) => (
<div className={cx('stdcm-card', { 'has-tip': hasTip, disabled })}>
<div data-testid="stdcm-card" className={cx('stdcm-card', { 'has-tip': hasTip, disabled })}>
{name && (
<div
className={cx(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,12 @@ const StdcmVias = ({ disabled = false, skipAnimation, onItineraryChange }: Stdcm
<StdcmCard
name={t('trainPath.vias')}
title={
<div className="stdcm-via-icons">
<div data-testid="stdcm-via-icons" className="stdcm-via-icons">
<div className="icon-bundle mt-1">
<img src={IntermediatePointIcon} alt="intermediate-point" />
<span className="icon-index">{pathStepIndex}</span>
<span data-testid="stdcm-icon-index" className="icon-index">
{pathStepIndex}
</span>
</div>
<button
data-testid="delete-via-button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const StopDurationInput = ({ pathStep }: StopDurationInputProps) => {
<div className="stop-time">
<Input
id="stdcm-via-stop-time"
data-testid="stdcm-via-stop-time"
type="text"
label={t('trainPath.stopFor')}
onChange={(e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,11 @@ const ManchetteWithSpaceTimeChartWrapper = ({
};

return (
<div ref={manchetteWithSpaceTimeCharWrappertRef} className="manchette-space-time-chart-wrapper">
<div
ref={manchetteWithSpaceTimeCharWrappertRef}
data-testid="manchette-space-time-chart"
className="manchette-space-time-chart-wrapper"
>
{waypointMenuData.activeWaypointId &&
manchetteWithSpaceTimeCharWrappertRef.current &&
createPortal(
Expand Down Expand Up @@ -399,6 +403,7 @@ const ManchetteWithSpaceTimeChartWrapper = ({
<Manchette {...manchettePropsWithWaypointMenu} height={height - BOTTOM_TOOLBAR_HEIGHT} />
<div
ref={spaceTimeChartRef}
data-testid="space-time-chart-container"
className="space-time-chart-container"
style={{
bottom: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const SpeedSpaceChartContainer = ({
<div
ref={root}
id="container-SpeedSpaceChart"
data-testid="speed-space-chart"
className="chart"
style={{ height: `${heightOfSpeedSpaceChartContainer}px` }}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ const TrainScheduleItem = ({
/>
</div>
<div title={train.trainName} className="checkbox-label">
<div className="train-info">
<div data-testid="train-info" className="train-info">
{projectionPathIsUsed && (
<div className="train-projected">
<Manchette iconColor="var(--white100)" />
Expand Down
2 changes: 1 addition & 1 deletion front/tests/002-project-management.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ test.describe('Validate the Operational Study Project workflow', () => {
});

// Navigate back to the Operational Studies page via the home page
await projectPage.goToHomePage();
await projectPage.backToHomePage();
await projectPage.goToOperationalStudiesPage();

// Reopen the updated project and validate the updated data
Expand Down
4 changes: 2 additions & 2 deletions front/tests/014-stdcm-linked-train.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ test.describe('Verify stdcm simulation page', () => {
towedRollingStockPrefilledValues.length
);
await linkedTrainSection.anteriorLinkedPathDetails();
await destinationSection.fillDestinationDetailsLight();
await viaSection.fillAndVerifyViaDetails({
viaNumber: 1,
ciSearchText: 'nS',
});
await destinationSection.fillDestinationDetailsLight();
await stdcmPage.launchSimulation();
await simulationResultPage.verifyTableData(
'./tests/assets/stdcm/linked-train/anterior-linked-train-table.json'
Expand All @@ -109,11 +109,11 @@ test.describe('Verify stdcm simulation page', () => {
towedRollingStockPrefilledValues.length
);
await linkedTrainSection.posteriorLinkedPathDetails();
await originSection.fillOriginDetailsLight('respectDestinationSchedule', true);
await viaSection.fillAndVerifyViaDetails({
viaNumber: 1,
ciSearchText: 'mid_east',
});
await originSection.fillOriginDetailsLight('respectDestinationSchedule', true);
await stdcmPage.launchSimulation();
await simulationResultPage.verifyTableData(
'./tests/assets/stdcm/linked-train/posterior-linked-train-table.json'
Expand Down
2 changes: 1 addition & 1 deletion front/tests/assets/constants/timeout-const.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const LOAD_PAGE_TIMEOUT = 30_000;
export const SIMULATION_RESULT_TIMEOUT = 30_000;
export const STDCM_SIMULATION_TIMEOUT = 30_000;
export const EXPLICIT_UI_STABILITY_TIMEOUT = 1_000;
export const EXPLICIT_UI_STABILITY_TIMEOUT = 500;
5 changes: 5 additions & 0 deletions front/tests/logging-fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ const testWithLogging = baseTest.extend<{ page: Page }>({
// Log before the test starts
logger.info(`START: '${testInfo.title}' | Browser: ${browserName}`);

// Handle uncaught exceptions
page.on('pageerror', (exception) => {
throw new Error(`Test failed due to uncaught exception: "${exception}"`);
});

// Run the actual test
await use(page);

Expand Down
1 change: 1 addition & 0 deletions front/tests/pages/home-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class HomePage extends CommonPage {
// Click on the logo to navigate back to the home page
async backToHomePage(): Promise<void> {
await this.backHomeLogo.click();
await this.page.waitForLoadState();
}

async goToOperationalStudiesPage(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { type Locator, type Page, expect } from '@playwright/test';

import {
EXPLICIT_UI_STABILITY_TIMEOUT,
SIMULATION_RESULT_TIMEOUT,
} from '../../assets/constants/timeout-const';
import OpSimulationResultPage from './simulation-results-page';
import { EXPLICIT_UI_STABILITY_TIMEOUT } from '../../assets/constants/timeout-const';
import { getTranslations } from '../../utils';
import readJsonFile from '../../utils/file-utils';
import type {
CommonTranslations,
FlatTranslations,
TimetableFilterTranslations,
} from '../../utils/types';
import CommonPage from '../common-page';

type ScenarioTranslations = {
timetable: FlatTranslations;
Expand All @@ -24,25 +21,14 @@ const frTranslations: ScenarioTranslations = readJsonFile(
'public/locales/fr/operationalStudies/scenario.json'
);

class ScenarioTimetableSection extends CommonPage {
class ScenarioTimetableSection extends OpSimulationResultPage {
private readonly invalidTrainsMessage: Locator;

private readonly timetableTrains: Locator;

private readonly selectedTimetableTrain: Locator;

// TODO: remove this commented code when the design of simulation bar has been changed
// readonly simulationBar: Locator;

private readonly manchetteSpaceTimeChart: Locator;

private readonly spaceTimeChart: Locator;
private readonly timetableTrainButton: Locator;

private readonly speedSpaceChart: Locator;

readonly timesStopsDataSheet: Locator;

private readonly simulationMap: Locator;
private readonly selectedTimetableTrain: Locator;

private readonly timetableTotalItemLabel: Locator;

Expand Down Expand Up @@ -90,14 +76,8 @@ class ScenarioTimetableSection extends CommonPage {
super(page);
this.invalidTrainsMessage = page.getByTestId('invalid-trains-message');
this.timetableTrains = page.getByTestId('scenario-timetable-train');
this.timetableTrainButton = page.getByTestId('train-info');
this.selectedTimetableTrain = page.locator('[data-testid="scenario-timetable-train"].selected');
// TODO: remove this commented code when the design of simulation bar has been changed
// this.simulationBar = page.locator('.osrd-simulation-sticky-bar');
this.manchetteSpaceTimeChart = page.locator('.manchette-space-time-chart-wrapper');
this.speedSpaceChart = page.locator('#container-SpeedSpaceChart');
this.spaceTimeChart = page.locator('.space-time-chart-container');
this.timesStopsDataSheet = page.locator('.time-stops-datasheet');
this.simulationMap = page.locator('.simulation-map');
this.timetableTotalItemLabel = page.locator('.toolbar-header .label');
this.timetableFilterButton = page.getByTestId('timetable-filter-button');
this.timetableFilterButtonClose = page.getByTestId('timetable-filter-button-close');
Expand Down Expand Up @@ -128,12 +108,7 @@ class ScenarioTimetableSection extends CommonPage {
this.scenarioCollapseButton = page.getByTestId('scenario-collapse-button');
this.timetableCollapseButton = page.getByTestId('timetable-collapse-button');
this.scenarioSideMenu = page.getByTestId('scenario-sidemenu');
this.simulationResult = page.locator('.simulation-results');
}

// Get the button locator of a train element.
static getTrainButton(trainSelector: Locator): Locator {
return trainSelector.getByTestId('scenario-timetable-train-button');
this.simulationResult = page.getByTestId('simulation-results');
}

// Verify that the message "The timetable contains invalid trains" is visible
Expand All @@ -152,26 +127,6 @@ class ScenarioTimetableSection extends CommonPage {
await expect(this.selectedTimetableTrain).toBeVisible();
}

// Verify that simulation results are displayed
async verifySimulationResultsVisibility(): Promise<void> {
await this.page.waitForLoadState('networkidle', { timeout: SIMULATION_RESULT_TIMEOUT });

const simulationResultsLocators = [
// TODO: remove this commented code when the design of simulation bar has been changed
// this.simulationBar,
this.manchetteSpaceTimeChart,
this.speedSpaceChart,
this.spaceTimeChart,
this.simulationMap,
this.timesStopsDataSheet,
];
await Promise.all(
simulationResultsLocators.map(async (simulationResultsLocator) => {
await expect(simulationResultsLocator).toBeVisible();
})
);
}

async checkTimetableFilterVisibilityLabelDefaultValue(
translation: FlatTranslations,
{
Expand Down Expand Up @@ -354,21 +309,14 @@ class ScenarioTimetableSection extends CommonPage {
const trainCount = await this.timetableTrains.count();

for (let currentTrainIndex = 0; currentTrainIndex < trainCount; currentTrainIndex += 1) {
await this.page.waitForLoadState();
await this.page.waitForLoadState('networkidle');
await this.simulationResult.waitFor();
const trainButton = ScenarioTimetableSection.getTrainButton(
this.timetableTrains.nth(currentTrainIndex)
);
await trainButton.click({ position: { x: 5, y: 5 } });
const trainButton = this.timetableTrainButton.nth(currentTrainIndex);
await trainButton.click();
await this.verifySimulationResultsVisibility();
}
}

async verifyTimesStopsDataSheetVisibility(): Promise<void> {
await expect(this.timesStopsDataSheet).toBeVisible({ timeout: SIMULATION_RESULT_TIMEOUT });
await this.timesStopsDataSheet.scrollIntoViewIfNeeded();
}

async clickOnEditTrain() {
await this.timetableTrains.first().hover();
await this.editTrainButton.click();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { type Locator, type Page } from '@playwright/test';
import { expect, type Locator, type Page } from '@playwright/test';

class OpSimulationResultPage {
readonly page: Page;
import { SIMULATION_RESULT_TIMEOUT } from '../../assets/constants/timeout-const';
import CommonPage from '../common-page';

class OpSimulationResultPage extends CommonPage {
private readonly speedSpaceChartSettingsButton: Locator;

private readonly speedSpaceChartCheckboxItems: Locator;
Expand All @@ -11,8 +12,23 @@ class OpSimulationResultPage {

private readonly speedSpaceChartCloseSettingsButton: Locator;

private readonly manchetteSpaceTimeChart: Locator;

private readonly spaceTimeChart: Locator;

private readonly speedSpaceChart: Locator;

readonly timesStopsDataSheet: Locator;

private readonly simulationMap: Locator;

constructor(page: Page) {
this.page = page;
super(page);
this.manchetteSpaceTimeChart = page.getByTestId('manchette-space-time-chart');
this.speedSpaceChart = page.getByTestId('speed-space-chart');
this.spaceTimeChart = page.getByTestId('space-time-chart-container');
this.timesStopsDataSheet = page.locator('.time-stops-datasheet');
this.simulationMap = page.getByTestId('simulation-map');
this.speedSpaceChartSettingsButton = page.locator('.interaction-button.elipsis-button');
this.speedSpaceChartCloseSettingsButton = page.locator('#close-settings-panel');
this.speedSpaceChartCheckboxItems = page.locator('#settings-panel .selection .checkmark');
Expand All @@ -29,6 +45,30 @@ class OpSimulationResultPage {
await this.speedSpaceChartCloseSettingsButton.click();
}

// Verify that simulation results are displayed
async verifySimulationResultsVisibility(): Promise<void> {
await this.page.waitForLoadState('networkidle', { timeout: SIMULATION_RESULT_TIMEOUT });

const simulationResultsLocators = [
this.manchetteSpaceTimeChart,
this.speedSpaceChart,
this.spaceTimeChart,
this.simulationMap,
this.timesStopsDataSheet,
];

await Promise.all(
simulationResultsLocators.map(async (simulationResultsLocator) => {
await expect(simulationResultsLocator).toBeVisible();
})
);
}

async verifyTimesStopsDataSheetVisibility(): Promise<void> {
await expect(this.timesStopsDataSheet).toBeVisible({ timeout: SIMULATION_RESULT_TIMEOUT });
await this.timesStopsDataSheet.scrollIntoViewIfNeeded();
}

// Ensures all checkboxes in the settings panel are checked.
async selectAllSpeedSpaceChartCheckboxes(): Promise<void> {
await this.openSettingsPanel();
Expand Down
2 changes: 1 addition & 1 deletion front/tests/pages/stdcm/consist-section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class ConsistSection {
await dropdownField.fill(selectedValue);
await dropdownField.press('ArrowDown');
await dropdownField.press('Enter');
await dropdownField.dispatchEvent('blur');
await dropdownField.blur();
await expect(dropdownField).toHaveValue(selectedValue);

const { expectedTonnage, expectedLength } = expectedValues;
Expand Down
Loading
Loading