Skip to content

Commit

Permalink
front: add speed space chart e2e test
Browse files Browse the repository at this point in the history
Signed-off-by: maymanaf <[email protected]>
  • Loading branch information
Maymanaf committed Dec 16, 2024
1 parent a64f77b commit bc38a36
Show file tree
Hide file tree
Showing 27 changed files with 195 additions and 2 deletions.
1 change: 1 addition & 0 deletions front/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default defineConfig({
/* Maximum time one test can run for. */
timeout: process.env.CI ? 90 * 1000 : 180 * 1000, // 90 seconds in CI, otherwise 180 seconds
expect: {
toHaveScreenshot: { maxDiffPixelRatio: 0.02 },
/**
* Maximum time expect() should wait for the condition to be met.
*/
Expand Down
100 changes: 99 additions & 1 deletion front/tests/012-op-simulation-settings-tab.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { expect } from '@playwright/test';

import type {
ElectricalProfileSet,
Infra,
Expand All @@ -11,6 +13,7 @@ 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 RoutePage from './pages/op-route-page-model';
import OpSimulationResultPage from './pages/op-simulation-results-page-model';
import OperationalStudiesSimulationSettingsPage from './pages/op-simulation-settings-page-model';
import OperationalStudiesTimetablePage from './pages/op-timetable-page-model';
import OperationalStudiesPage from './pages/operational-studies-page-model';
Expand Down Expand Up @@ -84,7 +87,7 @@ test.describe('Simulation Settings Tab Verification', () => {
test.beforeEach(
'Navigate to Times and Stops tab with rolling stock and route set',
async ({ page, browserName }) => {
stabilityTimeout = browserName === 'webkit' ? 2000 : 500;
stabilityTimeout = browserName === 'webkit' ? 2000 : 1000;
const [operationalStudiesPage, routePage, rollingStockPage, homePage] = [
new OperationalStudiesPage(page),
new RoutePage(page),
Expand All @@ -106,6 +109,7 @@ test.describe('Simulation Settings Tab Verification', () => {
await page.goto(
`/operational-studies/projects/${project.id}/studies/${study.id}/scenarios/${scenario.id}`
);
await homePage.removeViteOverlay();
// Wait for infra to be in 'CACHED' state before proceeding
await waitForInfraStateToBeCached(infra.id);
// Add a new train and set its properties
Expand Down Expand Up @@ -134,13 +138,16 @@ test.describe('Simulation Settings Tab Verification', () => {
opTimetablePage,
opOutputTablePage,
opSimulationSettingsPage,
simulationResultPage,
] = [
new OperationalStudiesPage(page),
new OperationalStudiesInputTablePage(page),
new OperationalStudiesTimetablePage(page),
new OperationalStudiesOutputTablePage(page),
new OperationalStudiesSimulationSettingsPage(page),
new OpSimulationResultPage(page),
];

// Project selected language
const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
const cell: CellData = {
Expand All @@ -167,6 +174,18 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('11:53');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();
await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-ElectricalProfileActivated.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await scrollContainer(page, '.time-stop-outputs .time-stops-datasheet .dsg-container');
await opOutputTablePage.getOutputTableData(expectedCellDataElectricalProfileON, OSRDLanguage);
await opTimetablePage.clickOnTimetableCollapseButton();
Expand All @@ -179,6 +198,18 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('11:52');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();
await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-ElectricalProfileDisabled.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await opOutputTablePage.getOutputTableData(expectedCellDataElectricalProfileOFF, OSRDLanguage);
});
test('Activate composition code', async ({ page }) => {
Expand All @@ -188,12 +219,14 @@ test.describe('Simulation Settings Tab Verification', () => {
opTimetablePage,
opOutputTablePage,
opSimulationSettingsPage,
simulationResultPage,
] = [
new OperationalStudiesPage(page),
new OperationalStudiesInputTablePage(page),
new OperationalStudiesTimetablePage(page),
new OperationalStudiesOutputTablePage(page),
new OperationalStudiesSimulationSettingsPage(page),
new OpSimulationResultPage(page),
];

const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
Expand Down Expand Up @@ -221,6 +254,18 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('12:03');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();
await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-SpeedLimitTagActivated.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await scrollContainer(page, '.time-stop-outputs .time-stops-datasheet .dsg-container');
await opOutputTablePage.getOutputTableData(expectedCellDataCodeCompoON, OSRDLanguage);
await opTimetablePage.clickOnTimetableCollapseButton();
Expand All @@ -233,6 +278,18 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('11:52');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();
await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-SpeedLimitTagDisabled.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await opOutputTablePage.getOutputTableData(expectedCellDataCodeCompoOFF, OSRDLanguage);
});
test('Activate linear and mareco margin', async ({ page }) => {
Expand All @@ -242,12 +299,14 @@ test.describe('Simulation Settings Tab Verification', () => {
opTimetablePage,
opOutputTablePage,
opSimulationSettingsPage,
simulationResultPage,
] = [
new OperationalStudiesPage(page),
new OperationalStudiesInputTablePage(page),
new OperationalStudiesTimetablePage(page),
new OperationalStudiesOutputTablePage(page),
new OperationalStudiesSimulationSettingsPage(page),
new OpSimulationResultPage(page),
];

const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
Expand Down Expand Up @@ -284,6 +343,18 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('11:54');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();
await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-LinearMargin.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await scrollContainer(page, '.time-stop-outputs .time-stops-datasheet .dsg-container');
await opOutputTablePage.getOutputTableData(expectedCellDataLinearMargin, OSRDLanguage);
await opTimetablePage.clickOnTimetableCollapseButton();
Expand All @@ -296,6 +367,18 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('11:54');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();
await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-MarecoMargin.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await opOutputTablePage.getOutputTableData(expectedCellDataMarecoMargin, OSRDLanguage);
});
test('Add all the simulation settings', async ({ page }) => {
Expand All @@ -305,12 +388,14 @@ test.describe('Simulation Settings Tab Verification', () => {
opTimetablePage,
opOutputTablePage,
opSimulationSettingsPage,
simulationResultPage,
] = [
new OperationalStudiesPage(page),
new OperationalStudiesInputTablePage(page),
new OperationalStudiesTimetablePage(page),
new OperationalStudiesOutputTablePage(page),
new OperationalStudiesSimulationSettingsPage(page),
new OpSimulationResultPage(page),
];

const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
Expand Down Expand Up @@ -348,6 +433,19 @@ test.describe('Simulation Settings Tab Verification', () => {
await opTimetablePage.getTrainArrivalTime('12:06');
await opTimetablePage.clickOnScenarioCollapseButton();
await opOutputTablePage.verifyTimesStopsDataSheetVisibility();

await performOnSpecificOSAndBrowser(
async () => {
await simulationResultPage.selectAllSpeedSpaceChartCheckboxes();
await expect(simulationResultPage.speedSpaceChartTabindexElement).toHaveScreenshot(
'SpeedSpaceChart-AllSettingsEnabled.png'
);
},
{
currentBrowser: browserName,
actionName: 'visual assertion',
}
);
await scrollContainer(page, '.time-stop-outputs .time-stops-datasheet .dsg-container');
await opOutputTablePage.getOutputTableData(expectedCellDataForAllSettings, OSRDLanguage);
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions front/tests/pages/common-page-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class CommonPage {
await this.viteOverlay.evaluate((node) => node.setAttribute('style', 'display:none;'));
}
}

async closeToastNotification(): Promise<void> {
const closeToastElements = await this.closeToastButton.all();
await Promise.all(closeToastElements.map((closeToastElement) => closeToastElement.click()));
}
}

export default CommonPage;
2 changes: 1 addition & 1 deletion front/tests/pages/op-output-table-page-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class OperationalStudiesOutputTablePage extends OperationalStudiesTimetablePage
// Wait for the Times and Stops simulation data sheet to be fully loaded with a specified timeout (default: 60 seconds)
async verifyTimesStopsDataSheetVisibility(timeout = 60 * 1000): Promise<void> {
await this.timesStopsDataSheet.waitFor({ state: 'visible', timeout });
await this.page.waitForTimeout(100); // Short delay for stabilization
await this.page.waitForTimeout(1000); // Short delay for stabilization
await this.timesStopsDataSheet.scrollIntoViewIfNeeded({ timeout });
}
}
Expand Down
53 changes: 53 additions & 0 deletions front/tests/pages/op-simulation-results-page-model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { expect, type Locator, type Page } from '@playwright/test';

class OpSimulationResultPage {
readonly page: Page;

private readonly speedSpaceChartSettingsButton: Locator;

private readonly sscCloseEllipsis: Locator;

private readonly sscCheckmarks: Locator;

readonly speedSpaceChartCloseSettingsButton: Locator;

constructor(page: Page) {
this.page = page;
this.speedSpaceChartSettingsButton = page.locator('.interaction-button.elipsis-button');
this.speedSpaceChartCloseSettingsButton = page.locator('#close-settings-panel');
this.speedSpaceChartCheckboxItems = page.locator('#settings-panel .selection .checkmark');
this.speedSpaceChartTabindexElement = page.locator(
'#container-SpeedSpaceChart > div[tabindex="0"]'
);
}

private async openSettingsPanel(): Promise<void> {
await this.sscEllipsisButton.click();
}

private async closeSettingsPanel(): Promise<void> {
await this.sscCloseEllipsis.click();
}

// Toggles the checkbox at a specific index if it is not already checked.
private async toggleCheckboxIfUnchecked(index: number): Promise<void> {
const checkbox = this.sscCheckboxes.nth(index);
const isChecked = await checkbox.isChecked();

if (!isChecked) {
await this.sscCheckmarks.nth(index).click();
}
await expect(checkbox).toBeChecked();
}

// Ensures all checkboxes in the settings panel are checked.
async checkAllSscCheckboxes(): Promise<void> {
await this.openSettingsPanel();

const checkboxes = await this.speedSpaceChartCheckboxItems.all();
await Promise.all(checkboxes.map((checkbox) => checkbox.setChecked(true, { force: true })));
await this.closeSettingsPanel();
}
}

export default OpSimulationResultPage;
36 changes: 36 additions & 0 deletions front/tests/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,39 @@ export const waitForInfraStateToBeCached = async (infraId: number): Promise<void

throw new Error("Infrastructure state did not reach 'CACHED' within the allotted 3 minutes.");
};

/**
* Perform an action only on a specified OS or a specific browser.
* @param action - The action to perform.
* @param options - Configuration options:
* - `currentBrowser`: The name of the current browser.
* - `os`: The target OS to run the action on (default: 'linux').
* - `browser`: The browser to use (default: 'chromium' and 'firefox').
* - `skipMessage`: Message to log if the action is skipped.
*/
export async function performOnSpecificOSAndBrowser(
action: () => Promise<void>,
options: {
currentBrowser?: string;
os?: NodeJS.Platform;
browsers?: string[];
actionName?: string;
skipMessage?: string;
}
) {
const {
currentBrowser,
os = 'linux',
browsers = ['chromium', 'firefox'],
actionName = 'action',
skipMessage = `Skipping ${actionName} as the platform is not ${os} or the browser${browsers.length > 1 ? 's are not' : ' is not'} ${browsers.join(', ')}.`,
} = options;

const currentOS = process.platform;

if (currentOS === os && currentBrowser && browsers.includes(currentBrowser)) {
await action();
} else {
console.info(skipMessage);
}
}

0 comments on commit bc38a36

Please sign in to comment.