From 9a51e02cd7ece560ce14a25e148ef0711cdbb0a5 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Thu, 7 Aug 2025 16:59:08 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A8(e2e)=20upgrade=20eslint=20to=20v9?= =?UTF-8?q?=20with=20e2e=20app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We upgraded ESLint to version 9 in the e2e app, which includes several improvements and fixes. This change also involves updating the ESLint configuration files to the new format and ensuring compatibility with the latest ESLint features. --- src/frontend/apps/e2e/.eslintrc.js | 9 -------- .../e2e/__tests__/app-impress/auth.setup.ts | 11 ++++++---- .../e2e/__tests__/app-impress/config.spec.ts | 2 +- .../__tests__/app-impress/doc-editor.spec.ts | 8 ++----- .../app-impress/doc-grid-dnd.spec.ts | 9 +++----- .../__tests__/app-impress/doc-header.spec.ts | 3 --- .../app-impress/doc-member-list.spec.ts | 3 --- .../__tests__/app-impress/doc-routing.spec.ts | 1 - .../__tests__/app-impress/doc-tree.spec.ts | 1 - .../app-impress/doc-visibility.spec.ts | 21 ++++++++++++++----- .../e2e/__tests__/app-impress/header.spec.ts | 1 - .../e2e/__tests__/app-impress/home.spec.ts | 1 - .../e2e/__tests__/app-impress/utils-common.ts | 2 +- src/frontend/apps/e2e/eslint.config.mjs | 20 ++++++++++++++++++ src/frontend/apps/e2e/package.json | 2 +- src/frontend/apps/e2e/tsconfig.json | 4 ++-- .../apps/e2e/type/convert-stream.d.ts | 2 +- 17 files changed, 54 insertions(+), 46 deletions(-) delete mode 100644 src/frontend/apps/e2e/.eslintrc.js create mode 100644 src/frontend/apps/e2e/eslint.config.mjs diff --git a/src/frontend/apps/e2e/.eslintrc.js b/src/frontend/apps/e2e/.eslintrc.js deleted file mode 100644 index 46f10c31..00000000 --- a/src/frontend/apps/e2e/.eslintrc.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - root: true, - extends: ['impress/playwright'], - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, - ignorePatterns: ['node_modules'], -}; diff --git a/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts b/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts index 2b7a4e04..b569b662 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts @@ -5,14 +5,19 @@ import { keyCloakSignIn } from './utils-common'; const saveStorageState = async ( browserConfig: FullProject, ) => { - const browserName = browserConfig?.name || 'chromium'; + if (!browserConfig) { + throw new Error('No browser config found'); + } - const { storageState, ...useConfig } = browserConfig?.use; + const browserName = browserConfig.name || 'chromium'; + + const { storageState, ...useConfig } = browserConfig.use; const browser = await chromium.launch(); const context = await browser.newContext(useConfig); const page = await context.newPage(); try { + // eslint-disable-next-line playwright/no-networkidle await page.goto('/', { waitUntil: 'networkidle' }); await page.content(); await expect(page.getByText('Docs').first()).toBeVisible(); @@ -45,11 +50,9 @@ const saveStorageState = async ( }; async function globalSetup(config: FullConfig) { - /* eslint-disable @typescript-eslint/no-non-null-assertion */ const chromeConfig = config.projects.find((p) => p.name === 'chromium')!; const firefoxConfig = config.projects.find((p) => p.name === 'firefox')!; const webkitConfig = config.projects.find((p) => p.name === 'webkit')!; - /* eslint-enable @typescript-eslint/no-non-null-assertion */ await saveStorageState(chromeConfig); await saveStorageState(webkitConfig); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts index c7186139..c5410c7c 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/config.spec.ts @@ -50,7 +50,7 @@ test.describe('Config', () => { await expect(image).toBeVisible(); // Wait for the media-check to be processed - // eslint-disable-next-line playwright/no-wait-for-timeout + await page.waitForTimeout(1000); // Check src of image diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts index 3cc3fee6..cdfa6ccc 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-editor.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable playwright/no-conditional-expect */ import path from 'path'; import { chromium, expect, test } from '@playwright/test'; @@ -214,7 +215,6 @@ test.describe('Doc Editor', () => { }); test('it saves the doc when we quit pages', async ({ page, browserName }) => { - // eslint-disable-next-line playwright/no-skipped-test test.skip(browserName === 'webkit', 'This test is very flaky with webkit'); // Check the first doc @@ -279,7 +279,7 @@ test.describe('Doc Editor', () => { await expect(image).toBeVisible(); // Wait for the media-check to be processed - // eslint-disable-next-line playwright/no-wait-for-timeout + await page.waitForTimeout(1000); // Check src of image @@ -397,8 +397,6 @@ test.describe('Doc Editor', () => { const editor = page.locator('.ProseMirror'); await editor.getByText('Hello').selectText(); - /* eslint-disable playwright/no-conditional-expect */ - /* eslint-disable playwright/no-conditional-in-test */ if (!ai_transform && !ai_translate) { await expect(page.getByRole('button', { name: 'AI' })).toBeHidden(); return; @@ -425,8 +423,6 @@ test.describe('Doc Editor', () => { page.getByRole('menuitem', { name: 'Language' }), ).toBeHidden(); } - /* eslint-enable playwright/no-conditional-expect */ - /* eslint-enable playwright/no-conditional-in-test */ }); }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid-dnd.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid-dnd.spec.ts index 7298c5ee..ee41ce29 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid-dnd.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid-dnd.spec.ts @@ -36,9 +36,8 @@ test.describe('Doc grid dnd', () => { expect(draggableBoundingBox).toBeDefined(); expect(dropZoneBoundingBox).toBeDefined(); - // eslint-disable-next-line playwright/no-conditional-in-test if (!draggableBoundingBox || !dropZoneBoundingBox) { - throw new Error('Impossible de déterminer la position des éléments'); + throw new Error('Unable to determine the position of the elements'); } await page.mouse.move( @@ -86,9 +85,8 @@ test.describe('Doc grid dnd', () => { const noDropAndNoDragBoundigBox = await noDropAndNoDrag.boundingBox(); - // eslint-disable-next-line playwright/no-conditional-in-test if (!canDropAndDragBoundigBox || !noDropAndNoDragBoundigBox) { - throw new Error('Impossible de déterminer la position des éléments'); + throw new Error('Unable to determine the position of the elements'); } await page.mouse.move( @@ -137,9 +135,8 @@ test.describe('Doc grid dnd', () => { const noDropAndNoDragBoundigBox = await noDropAndNoDrag.boundingBox(); - // eslint-disable-next-line playwright/no-conditional-in-test if (!canDropAndDragBoundigBox || !noDropAndNoDragBoundigBox) { - throw new Error('Impossible de déterminer la position des éléments'); + throw new Error('Unable to determine the position of the elements'); } await page.mouse.move( diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts index 76f02b75..b76f718e 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts @@ -316,7 +316,6 @@ test.describe('Doc Header', () => { page, browserName, }) => { - // eslint-disable-next-line playwright/no-skipped-test test.skip( browserName === 'webkit', 'navigator.clipboard is not working with webkit and playwright', @@ -351,7 +350,6 @@ test.describe('Doc Header', () => { }); test('It checks the copy as HTML button', async ({ page, browserName }) => { - // eslint-disable-next-line playwright/no-skipped-test test.skip( browserName === 'webkit', 'navigator.clipboard is not working with webkit and playwright', @@ -386,7 +384,6 @@ test.describe('Doc Header', () => { }); test('it checks the copy link button', async ({ page, browserName }) => { - // eslint-disable-next-line playwright/no-skipped-test test.skip( browserName === 'webkit', 'navigator.clipboard is not working with webkit and playwright', diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts index 47597069..d6357658 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-list.spec.ts @@ -151,7 +151,6 @@ test.describe('Document list members', () => { await expect(soloOwner).toBeVisible(); await list.click({ - // eslint-disable-next-line playwright/no-force-option force: true, // Force click to close the dropdown }); const newUserEmail = await addNewMember(page, 0, 'Owner'); @@ -163,13 +162,11 @@ test.describe('Document list members', () => { await currentUserRole.click(); await expect(soloOwner).toBeHidden(); await list.click({ - // eslint-disable-next-line playwright/no-force-option force: true, // Force click to close the dropdown }); await newUserRoles.click(); await list.click({ - // eslint-disable-next-line playwright/no-force-option force: true, // Force click to close the dropdown }); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts index 21683bbb..1d64435f 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts @@ -40,7 +40,6 @@ test.describe('Doc Routing', () => { }); test('checks 404 on docs/[id] page', async ({ page }) => { - // eslint-disable-next-line playwright/no-wait-for-timeout await page.waitForTimeout(300); await page.goto('/docs/some-unknown-doc'); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts index a3d52c16..a22c38ba 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-tree.spec.ts @@ -1,4 +1,3 @@ -/* eslint-disable playwright/no-conditional-in-test */ import { expect, test } from '@playwright/test'; import { diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts index eca0a019..04cff709 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-visibility.spec.ts @@ -15,7 +15,6 @@ test.describe('Doc Visibility', () => { }); test('It checks the copy link button', async ({ page, browserName }) => { - // eslint-disable-next-line playwright/no-skipped-test test.skip( browserName === 'webkit', 'navigator.clipboard is not working with webkit and playwright', @@ -119,8 +118,11 @@ test.describe('Doc Visibility: Restricted', () => { .click(); const otherBrowser = BROWSERS.find((b) => b !== browserName); + if (!otherBrowser) { + throw new Error('No alternative browser found'); + } - await keyCloakSignIn(page, otherBrowser!); + await keyCloakSignIn(page, otherBrowser); await expect(page.getByTestId('header-logo-link')).toBeVisible({ timeout: 10000, @@ -151,6 +153,9 @@ test.describe('Doc Visibility: Restricted', () => { }); const otherBrowser = BROWSERS.find((b) => b !== browserName); + if (!otherBrowser) { + throw new Error('No alternative browser found'); + } const username = `user@${otherBrowser}.test`; await inputSearch.fill(username); await page.getByRole('option', { name: username }).click(); @@ -174,7 +179,7 @@ test.describe('Doc Visibility: Restricted', () => { }) .click(); - await keyCloakSignIn(page, otherBrowser!); + await keyCloakSignIn(page, otherBrowser); await expect(page.getByTestId('header-logo-link')).toBeVisible(); @@ -449,7 +454,10 @@ test.describe('Doc Visibility: Authenticated', () => { .click(); const otherBrowser = BROWSERS.find((b) => b !== browserName); - await keyCloakSignIn(page, otherBrowser!); + if (!otherBrowser) { + throw new Error('No alternative browser found'); + } + await keyCloakSignIn(page, otherBrowser); await expect(page.getByTestId('header-logo-link')).toBeVisible({ timeout: 10000, @@ -538,7 +546,10 @@ test.describe('Doc Visibility: Authenticated', () => { .click(); const otherBrowser = BROWSERS.find((b) => b !== browserName); - await keyCloakSignIn(page, otherBrowser!); + if (!otherBrowser) { + throw new Error('No alternative browser found'); + } + await keyCloakSignIn(page, otherBrowser); await expect(page.getByTestId('header-logo-link')).toBeVisible({ timeout: 10000, diff --git a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts index c0e534ec..1b92bf18 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts @@ -76,7 +76,6 @@ test.describe('Header', () => { * La gaufre load a js file from a remote server, * it takes some time to load the file and have the interaction available */ - // eslint-disable-next-line playwright/no-wait-for-timeout await page.waitForTimeout(1500); await header diff --git a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts index 9465158c..28f479f4 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/home.spec.ts @@ -72,7 +72,6 @@ test.describe('Home page', () => { await page.waitForLoadState('domcontentloaded'); // Wait a bit more for the responsive store to be initialized - // eslint-disable-next-line playwright/no-wait-for-timeout await page.waitForTimeout(500); // Check header content diff --git a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts index 6b340b08..dbab861d 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/utils-common.ts @@ -27,7 +27,7 @@ export const CONFIG = { export const overrideConfig = async ( page: Page, - newConfig: { [K in keyof typeof CONFIG]?: unknown }, + newConfig: { [_K in keyof typeof CONFIG]?: unknown }, ) => await page.route('**/api/v1.0/config/', async (route) => { const request = route.request(); diff --git a/src/frontend/apps/e2e/eslint.config.mjs b/src/frontend/apps/e2e/eslint.config.mjs new file mode 100644 index 00000000..461c01c9 --- /dev/null +++ b/src/frontend/apps/e2e/eslint.config.mjs @@ -0,0 +1,20 @@ +import { defineConfig } from '@eslint/config-helpers'; +import docsPlugin from 'eslint-plugin-docs'; + +const eslintConfig = defineConfig([ + { + files: ['**/*.ts', '**/*.mjs'], + plugins: { + docs: docsPlugin, + }, + extends: ['docs/playwright'], + languageOptions: { + parserOptions: { + tsconfigRootDir: import.meta.dirname, + project: ['./tsconfig.json'], + }, + }, + }, +]); + +export default eslintConfig; diff --git a/src/frontend/apps/e2e/package.json b/src/frontend/apps/e2e/package.json index ae305e5e..7fd1edcb 100644 --- a/src/frontend/apps/e2e/package.json +++ b/src/frontend/apps/e2e/package.json @@ -3,7 +3,7 @@ "version": "3.6.0", "private": true, "scripts": { - "lint": "eslint . --ext .ts", + "lint": "eslint", "install-playwright": "playwright install --with-deps", "test": "playwright test", "test:ui": "yarn test --ui", diff --git a/src/frontend/apps/e2e/tsconfig.json b/src/frontend/apps/e2e/tsconfig.json index a9aa4817..64fe2454 100644 --- a/src/frontend/apps/e2e/tsconfig.json +++ b/src/frontend/apps/e2e/tsconfig.json @@ -12,8 +12,8 @@ "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", - "incremental": true, + "incremental": true }, - "include": ["**/*.ts", "**/*.d.ts"], + "include": ["**/*.ts", "**/*.d.ts", "**/*.mjs"], "exclude": ["node_modules"] } diff --git a/src/frontend/apps/e2e/type/convert-stream.d.ts b/src/frontend/apps/e2e/type/convert-stream.d.ts index d79cbccc..93b753a9 100644 --- a/src/frontend/apps/e2e/type/convert-stream.d.ts +++ b/src/frontend/apps/e2e/type/convert-stream.d.ts @@ -1,5 +1,5 @@ declare module 'convert-stream' { export function toBuffer( - readableStream: NodeJS.ReadableStream, + _readableStream: NodeJS.ReadableStream, ): Promise; }