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: reduce e2e test execution time #10423

Merged
merged 2 commits into from
Feb 4, 2025
Merged
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
39 changes: 6 additions & 33 deletions front/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,29 @@
import { defineConfig, devices } from '@playwright/test';
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',

/* Maximum time one test can run for. */
timeout: process.env.CI ? 90 * 1000 : 180 * 1000, // 90 seconds in CI, otherwise 180 seconds
timeout: 90_000,
expect: {
toHaveScreenshot: { maxDiffPixelRatio: 0.02 },
/**
* Maximum time expect() should wait for the condition to be met.
*/
timeout: process.env.CI ? 10 * 1000 : 30 * 1000, // 10 seconds in CI, otherwise 30 seconds
timeout: 10_000,
},

/* Run tests in files in parallel */
fullyParallel: true,
/*
* Limit parallelism in CI based on CPU capacity,
* running 50% of the available workers when in CI.
* Otherwise, run tests with a single worker.
*/
workers: process.env.CI ? '50%' : 1,
/* Fail the build on CI if you accidentally left test.only in the source code. */
workers: '50%',
forbidOnly: !!process.env.CI,
/* Retry up to 2 times on CI, and 1 time otherwise */
retries: process.env.CI ? 2 : 1,
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
retries: 1,
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
navigationTimeout: 30_000,
actionTimeout: 15_000,
baseURL: process.env.BASE_URL || 'http://localhost:4000',

/* Collect trace and video when retrying the first failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
video: 'on-first-retry',

/* Set locale and timezone */
locale: 'fr',
timezoneId: 'Europe/Paris',
},
reporter: process.env.CI ? 'github' : [['line'], ['html']],

/* Configure projects for major browsers */
projects: [
{ name: 'setup', testMatch: 'global-setup.ts', teardown: 'teardown' },
{
Expand Down
12 changes: 7 additions & 5 deletions front/tests/001-home-page.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { expect } from '@playwright/test';

import test from './logging-fixture';
import HomePage from './pages/home-page-model';
import test from './test-logger';
import { getTranslations } from './utils';
import enTranslations from '../public/locales/en/home/home.json';
import frTranslations from '../public/locales/fr/home/home.json';

test.describe('Home page OSRD', () => {
let homePage: HomePage;
let OSRDLanguage: string;

test.beforeEach('Navigate to the home page', async ({ page }) => {
homePage = new HomePage(page);
await homePage.goToHomePage();
OSRDLanguage = await homePage.getOSRDLanguage();
});

test.afterEach('Returns to the home page', async () => {
Expand All @@ -20,8 +20,10 @@ test.describe('Home page OSRD', () => {

/** *************** Test 1 **************** */
test('Verify the links for different pages in Home Page', async () => {
// Determine the correct translations based on the selected language
const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
const translations = getTranslations({
en: enTranslations,
fr: frTranslations,
});

// List of expected links on the home page
const expectedLinks = [
Expand Down
23 changes: 9 additions & 14 deletions front/tests/002-project-management.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import type { Project } from 'common/api/osrdEditoastApi';

import projectData from './assets/operationStudies/project.json';
import HomePage from './pages/home-page-model';
import test from './logging-fixture';
import ProjectPage from './pages/project-page-model';
import test from './test-logger';
import { generateUniqueName } from './utils';
import { createProject } from './utils/setup-utils';
import { deleteProject } from './utils/teardown-utils';

test.describe('Validate the Operational Study Project workflow', () => {
let project: Project;
let projectPage: ProjectPage;

test.beforeEach(async ({ page }) => {
projectPage = new ProjectPage(page);
});

/** *************** Test 1 **************** */
test('Create a new project', async ({ page }) => {
const projectPage = new ProjectPage(page);

// Navigate to the Operational Studies projects page
// Go to projects page
await page.goto('/operational-studies/projects');

// Define a unique project name for the test
Expand Down Expand Up @@ -49,12 +51,8 @@ test.describe('Validate the Operational Study Project workflow', () => {
test('Update an existing project', async ({ page }) => {
// Create a project
project = await createProject(generateUniqueName(projectData.name));

// Navigate to the Operational Studies projects page
await page.goto('/operational-studies/projects');

const homePage = new HomePage(page);
const projectPage = new ProjectPage(page);
// Open the created project by name using the project page model
await projectPage.openProjectByTestId(project.name);

Expand All @@ -69,8 +67,8 @@ test.describe('Validate the Operational Study Project workflow', () => {
});

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

// Reopen the updated project and validate the updated data
await projectPage.openProjectByTestId(`${project.name} (updated)`);
Expand All @@ -90,11 +88,8 @@ test.describe('Validate the Operational Study Project workflow', () => {
test('Delete a project', async ({ page }) => {
// Create a project
project = await createProject(generateUniqueName(projectData.name));

// Navigate to the Operational Studies projects page
await page.goto('/operational-studies/projects');

const projectPage = new ProjectPage(page);
// Find the project by name and delete it using the page model
await projectPage.openProjectByTestId(project.name);
await projectPage.deleteProject(project.name);
Expand Down
33 changes: 14 additions & 19 deletions front/tests/003-study-management.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,40 @@ import { v4 as uuidv4 } from 'uuid';
import type { Project, Study } from 'common/api/osrdEditoastApi';

import studyData from './assets/operationStudies/study.json';
import HomePage from './pages/home-page-model';
import test from './logging-fixture';
import StudyPage from './pages/study-page-model';
import test from './test-logger';
import { formatDateToDayMonthYear, generateUniqueName } from './utils';
import { generateUniqueName, getTranslations } from './utils';
import { getProject } from './utils/api-setup';
import { formatDateToDayMonthYear } from './utils/date';
import { createStudy } from './utils/setup-utils';
import { deleteStudy } from './utils/teardown-utils';
import enTranslations from '../public/locales/en/operationalStudies/study.json';
import frTranslations from '../public/locales/fr/operationalStudies/study.json';

test.describe('Validate the Study creation workflow', () => {
let studyPage: StudyPage;
let project: Project;
let study: Study;
let OSRDLanguage: string;
test.beforeAll(' Retrieve a project', async () => {
let translations: typeof enTranslations | typeof frTranslations;
test.beforeAll(' Retrieve a project and the translation', async () => {
project = await getProject();
translations = getTranslations({
en: enTranslations,
fr: frTranslations,
});
});

test.beforeEach('Create a new study linked to the project', async ({ page }) => {
const homePage = new HomePage(page);
await homePage.goToHomePage();
OSRDLanguage = await homePage.getOSRDLanguage();
test.beforeEach(async ({ page }) => {
studyPage = new StudyPage(page);
});

/** *************** Test 1 **************** */
test('Create a new study', async ({ page }) => {
const studyPage = new StudyPage(page);
// Navigate to project page
await page.goto(`/operational-studies/projects/${project.id}`);

// Set translations based on the language
const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
const studyName = `${studyData.name} ${uuidv4()}`; // Unique study name
const todayDateISO = new Date().toISOString().split('T')[0]; // Get today's date in ISO format
const expectedDate = formatDateToDayMonthYear(todayDateISO, OSRDLanguage);
const expectedDate = formatDateToDayMonthYear(todayDateISO);
// Create a new study using the study page model
await studyPage.createStudy({
name: studyName,
Expand Down Expand Up @@ -72,14 +71,12 @@ test.describe('Validate the Study creation workflow', () => {

/** *************** Test 2 **************** */
test('Update an existing study', async ({ page }) => {
const studyPage = new StudyPage(page);
// Create a study
study = await createStudy(project.id, generateUniqueName(studyData.name));
// Navigate to study page
await page.goto(`/operational-studies/projects/${project.id}/studies/${study.id}`);
const translations = OSRDLanguage === 'English' ? enTranslations : frTranslations;
const tomorrowDateISO = new Date(Date.now() + 86400000).toISOString().split('T')[0]; // Get tomorrow's date in ISO format
const expectedDate = formatDateToDayMonthYear(tomorrowDateISO, OSRDLanguage);
const expectedDate = formatDateToDayMonthYear(tomorrowDateISO);
// Update the study with new values
await studyPage.updateStudy({
name: `${study.name} (updated)`,
Expand Down Expand Up @@ -122,8 +119,6 @@ test.describe('Validate the Study creation workflow', () => {
// Create a study
study = await createStudy(project.id, generateUniqueName(studyData.name));

const studyPage = new StudyPage(page);

// Navigate to the list of studies for the project
await page.goto(`/operational-studies/projects/${project.id}`);

Expand Down
13 changes: 6 additions & 7 deletions front/tests/004-scenario-management.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import type { ElectricalProfileSet, Project, Scenario, Study } from 'common/api/

import scenarioData from './assets/operationStudies/scenario.json';
import { infrastructureName } from './assets/project-const';
import test from './logging-fixture';
import ScenarioPage from './pages/scenario-page-model';
import test from './test-logger';
import { generateUniqueName } from './utils';
import { deleteApiRequest, getProject, getStudy, setElectricalProfile } from './utils/api-setup';
import createScenario from './utils/scenario';
import { deleteScenario } from './utils/teardown-utils';

test.describe('Validate the Scenario creation workflow', () => {
let scenarioPage: ScenarioPage;
let project: Project;
let study: Study;
let scenario: Scenario;
Expand All @@ -27,10 +28,12 @@ test.describe('Validate the Scenario creation workflow', () => {
await deleteApiRequest(`/api/electrical_profile_set/${electricalProfileSet.id}/`);
});

test.beforeEach(async ({ page }) => {
scenarioPage = new ScenarioPage(page);
});

/** *************** Test 1 **************** */
test('Create a new scenario', async ({ page }) => {
const scenarioPage = new ScenarioPage(page);

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

Expand Down Expand Up @@ -59,8 +62,6 @@ test.describe('Validate the Scenario creation workflow', () => {
// Set up a scenario
({ project, study, scenario } = await createScenario());

const scenarioPage = new ScenarioPage(page);

// Navigate to the specific scenario page
await page.goto(`/operational-studies/projects/${project.id}/studies/${study.id}`);
await scenarioPage.openScenarioByTestId(scenario.name);
Expand Down Expand Up @@ -98,8 +99,6 @@ test.describe('Validate the Scenario creation workflow', () => {
// Set up a scenario
({ project, study, scenario } = await createScenario());

// Navigate to the specific scenario page
const scenarioPage = new ScenarioPage(page);
// Navigate to the specific scenario page
await page.goto(`/operational-studies/projects/${project.id}/studies/${study.id}`);
await scenarioPage.openScenarioByTestId(scenario.name);
Expand Down
19 changes: 12 additions & 7 deletions front/tests/005-operational-studies.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,21 @@ import type {
} from 'common/api/osrdEditoastApi';

import { electricRollingStockName } from './assets/project-const';
import test from './logging-fixture';
import RoutePage from './pages/op-route-page-model';
import OperationalStudiesPage from './pages/operational-studies-page-model';
import RollingStockSelectorPage from './pages/rollingstock-selector-page-model';
import test from './test-logger';
import { waitForInfraStateToBeCached } from './utils';
import { getInfra, getRollingStock } from './utils/api-setup';
import createScenario from './utils/scenario';
import { deleteScenario } from './utils/teardown-utils';

test.describe('Verify simulation configuration in operational studies', () => {
test.slow();

let rollingstockPage: RollingStockSelectorPage;
let operationalStudiesPage: OperationalStudiesPage;
let routePage: RoutePage;
let project: Project;
let study: Study;
let scenario: Scenario;
Expand All @@ -31,7 +35,13 @@ test.describe('Verify simulation configuration in operational studies', () => {
infra = await getInfra();
});

test.beforeEach('Set up the project, study, and scenario', async () => {
test.beforeEach('Set up the project, study, and scenario', async ({ page }) => {
[rollingstockPage, operationalStudiesPage, routePage] = [
new RollingStockSelectorPage(page),
new OperationalStudiesPage(page),
new RoutePage(page),
];

({ project, study, scenario } = await createScenario());
});

Expand All @@ -42,11 +52,6 @@ test.describe('Verify simulation configuration in operational studies', () => {
/** *************** Test **************** */
test('Pathfinding with rolling stock and composition code', async ({ page }) => {
// Page models
const [rollingstockPage, operationalStudiesPage, routePage] = [
new RollingStockSelectorPage(page),
new OperationalStudiesPage(page),
new RoutePage(page),
];

// Navigate to the scenario page for the given project and study
await page.goto(
Expand Down
Loading
Loading