diff --git a/jest.config.cli.js b/jest.config.cli.js index 4305d8b250..cf6e3b83bb 100644 --- a/jest.config.cli.js +++ b/jest.config.cli.js @@ -4,7 +4,7 @@ module.exports = { displayName: 'CLI tests', testMatch: ['**/?(*.)+(spec|test).cli.(js|ts)'], testEnvironment: 'node', - setupFilesAfterEnv: ['/../../../../../tests/setup/jest-cli.setup.js'], + setupFilesAfterEnv: ['/../../../../tests/setup/jest-cli.setup.js'], coveragePathIgnorePatterns: [ '/dist/', '/node_modules/', diff --git a/playwright.base.config.js b/playwright.base.config.js index 44ee7352a1..fa75de4e06 100644 --- a/playwright.base.config.js +++ b/playwright.base.config.js @@ -42,7 +42,7 @@ const createConfig = ({ port, testDir, appDir, reportFileName }) => ({ timeout: getEnvNum(process.env.PLAYWRIGHT_TIMEOUT, 90 * 1000), /* Global setup to set localStorage for all tests */ - globalSetup: require.resolve('./tests/e2e/browser/utils/global-setup.ts'), + globalSetup: require.resolve('./tests/utils/global-setup.ts'), expect: { /** @@ -96,7 +96,7 @@ const createConfig = ({ port, testDir, appDir, reportFileName }) => ({ : 'off', /* Use the storage state with localStorage set globally */ - storageState: './tests/e2e/browser/playwright-storage-state.json', + storageState: './tests/e2e/playwright-storage-state.json', }, /* Configure projects for major browsers */ diff --git a/tests/e2e/cli/README.md b/tests/cli/README.md similarity index 100% rename from tests/e2e/cli/README.md rename to tests/cli/README.md diff --git a/tests/cli/constants.js b/tests/cli/constants.js new file mode 100644 index 0000000000..ccaa228c8e --- /dev/null +++ b/tests/cli/constants.js @@ -0,0 +1,8 @@ +'use strict'; + +// Re-export from shared constants +const sharedConstants = require('../e2e/constants'); + +module.exports = { + CUSTOM_TRANSFER_TOKEN_ACCESS_KEY: sharedConstants.CUSTOM_TRANSFER_TOKEN_ACCESS_KEY, +}; diff --git a/tests/e2e/cli/data/README.md b/tests/cli/data/README.md similarity index 100% rename from tests/e2e/cli/data/README.md rename to tests/cli/data/README.md diff --git a/tests/cli/data/complex.tar.gz b/tests/cli/data/complex.tar.gz new file mode 100644 index 0000000000..1c6df83d16 Binary files /dev/null and b/tests/cli/data/complex.tar.gz differ diff --git a/tests/e2e/cli/jest.config.js b/tests/cli/jest.config.js similarity index 100% rename from tests/e2e/cli/jest.config.js rename to tests/cli/jest.config.js diff --git a/tests/e2e/cli/tests/strapi/config.js b/tests/cli/tests/strapi/config.js similarity index 100% rename from tests/e2e/cli/tests/strapi/config.js rename to tests/cli/tests/strapi/config.js diff --git a/tests/e2e/cli/tests/strapi/data-transfer/export.test.cli.js b/tests/cli/tests/strapi/data-transfer/export.test.cli.js similarity index 93% rename from tests/e2e/cli/tests/strapi/data-transfer/export.test.cli.js rename to tests/cli/tests/strapi/data-transfer/export.test.cli.js index 6f3dd74214..174f4cb292 100644 --- a/tests/e2e/cli/tests/strapi/data-transfer/export.test.cli.js +++ b/tests/cli/tests/strapi/data-transfer/export.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('export', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/data-transfer/import.test.cli.js b/tests/cli/tests/strapi/data-transfer/import.test.cli.js similarity index 96% rename from tests/e2e/cli/tests/strapi/data-transfer/import.test.cli.js rename to tests/cli/tests/strapi/data-transfer/import.test.cli.js index 205d6ec9be..b499e5e5bf 100644 --- a/tests/e2e/cli/tests/strapi/data-transfer/import.test.cli.js +++ b/tests/cli/tests/strapi/data-transfer/import.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('import', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/README.md b/tests/cli/tests/strapi/strapi/README.md similarity index 100% rename from tests/e2e/cli/tests/strapi/strapi/README.md rename to tests/cli/tests/strapi/strapi/README.md diff --git a/tests/e2e/cli/tests/strapi/strapi/content-types-list.test.cli.js b/tests/cli/tests/strapi/strapi/content-types-list.test.cli.js similarity index 99% rename from tests/e2e/cli/tests/strapi/strapi/content-types-list.test.cli.js rename to tests/cli/tests/strapi/strapi/content-types-list.test.cli.js index 2abfd7d427..80b89a9ad8 100644 --- a/tests/e2e/cli/tests/strapi/strapi/content-types-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/content-types-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('content-types:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/controllers-list.test.cli.js b/tests/cli/tests/strapi/strapi/controllers-list.test.cli.js similarity index 99% rename from tests/e2e/cli/tests/strapi/strapi/controllers-list.test.cli.js rename to tests/cli/tests/strapi/strapi/controllers-list.test.cli.js index 6381bf1810..dee473612c 100644 --- a/tests/e2e/cli/tests/strapi/strapi/controllers-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/controllers-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('controllers:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/hooks-list.test.cli.js b/tests/cli/tests/strapi/strapi/hooks-list.test.cli.js similarity index 96% rename from tests/e2e/cli/tests/strapi/strapi/hooks-list.test.cli.js rename to tests/cli/tests/strapi/strapi/hooks-list.test.cli.js index 4da7501a48..1622a4fb1c 100644 --- a/tests/e2e/cli/tests/strapi/strapi/hooks-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/hooks-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('hooks:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/middlewares-list.test.cli.js b/tests/cli/tests/strapi/strapi/middlewares-list.test.cli.js similarity index 98% rename from tests/e2e/cli/tests/strapi/strapi/middlewares-list.test.cli.js rename to tests/cli/tests/strapi/strapi/middlewares-list.test.cli.js index cbafa2bcdb..b60d35c7d8 100644 --- a/tests/e2e/cli/tests/strapi/strapi/middlewares-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/middlewares-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('middlewares:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/openapi-generate.test.cli.ts b/tests/cli/tests/strapi/strapi/openapi-generate.test.cli.ts similarity index 100% rename from tests/e2e/cli/tests/strapi/strapi/openapi-generate.test.cli.ts rename to tests/cli/tests/strapi/strapi/openapi-generate.test.cli.ts diff --git a/tests/e2e/cli/tests/strapi/strapi/policies-list.test.cli.js b/tests/cli/tests/strapi/strapi/policies-list.test.cli.js similarity index 97% rename from tests/e2e/cli/tests/strapi/strapi/policies-list.test.cli.js rename to tests/cli/tests/strapi/strapi/policies-list.test.cli.js index 2277c6b304..36c1494a28 100644 --- a/tests/e2e/cli/tests/strapi/strapi/policies-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/policies-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('policies:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/routes-list.test.cli.js b/tests/cli/tests/strapi/strapi/routes-list.test.cli.js similarity index 99% rename from tests/e2e/cli/tests/strapi/strapi/routes-list.test.cli.js rename to tests/cli/tests/strapi/strapi/routes-list.test.cli.js index f24002f59d..137a9ba24b 100644 --- a/tests/e2e/cli/tests/strapi/strapi/routes-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/routes-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('routes:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/services-list.test.cli.js b/tests/cli/tests/strapi/strapi/services-list.test.cli.js similarity index 99% rename from tests/e2e/cli/tests/strapi/strapi/services-list.test.cli.js rename to tests/cli/tests/strapi/strapi/services-list.test.cli.js index b37a7b9a21..46e52b4132 100644 --- a/tests/e2e/cli/tests/strapi/strapi/services-list.test.cli.js +++ b/tests/cli/tests/strapi/strapi/services-list.test.cli.js @@ -2,7 +2,7 @@ const coffee = require('coffee'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('services:list', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/strapi/version.test.cli.js b/tests/cli/tests/strapi/strapi/version.test.cli.js similarity index 95% rename from tests/e2e/cli/tests/strapi/strapi/version.test.cli.js rename to tests/cli/tests/strapi/strapi/version.test.cli.js index 8b004dfc22..bef99b844d 100644 --- a/tests/e2e/cli/tests/strapi/strapi/version.test.cli.js +++ b/tests/cli/tests/strapi/strapi/version.test.cli.js @@ -4,7 +4,7 @@ const coffee = require('coffee'); const semver = require('semver'); const assert = require('assert'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('--version', () => { let appPath; diff --git a/tests/e2e/cli/tests/strapi/version/version.test.cli.js b/tests/cli/tests/strapi/version/version.test.cli.js similarity index 95% rename from tests/e2e/cli/tests/strapi/version/version.test.cli.js rename to tests/cli/tests/strapi/version/version.test.cli.js index bfd64f96b1..8ec49df73a 100644 --- a/tests/e2e/cli/tests/strapi/version/version.test.cli.js +++ b/tests/cli/tests/strapi/version/version.test.cli.js @@ -4,7 +4,7 @@ const coffee = require('coffee'); const semver = require('semver'); const assert = require('assert'); -const utils = require('../../../utils'); +const utils = require('../../../../utils'); describe('--version', () => { let appPath; diff --git a/tests/cli/utils/index.js b/tests/cli/utils/index.js new file mode 100644 index 0000000000..60e850c560 --- /dev/null +++ b/tests/cli/utils/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + fs: require('../../utils/fs'), + seed: require('../../utils/scripts/dts-import'), + instances: require('../../utils/test-app'), + helpers: require('../../utils/helpers'), +}; diff --git a/tests/e2e/browser/README.md b/tests/e2e/README.md similarity index 100% rename from tests/e2e/browser/README.md rename to tests/e2e/README.md diff --git a/tests/e2e/cli/constants.js b/tests/e2e/cli/constants.js deleted file mode 100644 index 27667c32e0..0000000000 --- a/tests/e2e/cli/constants.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -const { CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } = require('../app-template/src/constants'); - -module.exports = { - CUSTOM_TRANSFER_TOKEN_ACCESS_KEY, -}; diff --git a/tests/e2e/cli/scripts/dts-export.js b/tests/e2e/cli/scripts/dts-export.js deleted file mode 100644 index ce27b21498..0000000000 --- a/tests/e2e/cli/scripts/dts-export.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict'; - -const { - strapi: { - providers: { createLocalStrapiSourceProvider }, - }, - file: { - providers: { createLocalFileDestinationProvider }, - }, - engine: { createTransferEngine }, -} = require('@strapi/data-transfer'); -const { createStrapi, compileStrapi } = require('@strapi/strapi'); -const path = require('path'); - -/** - * Export the data from a strapi project. - * This script should be run as `node /dts-export.js [exportFilePath]` from the - * root directory of a strapi project e.g. `/examples/kitchensink`. - */ -const createDataset = async () => { - let args = process.argv.slice(2); - - if (args.length !== 1) { - console.error('Please provide the dataset path name as a parameter.'); - process.exit(1); - } - - const datasetPath = path.resolve(args[0]); - - const strapi = await createStrapiInstance(); - - const source = createSourceProvider(strapi); - const destination = createDestinationProvider(datasetPath); - - const engine = createTransferEngine(source, destination, { - versionStrategy: 'ignore', - schemaStrategy: 'ignore', - }); - - engine.diagnostics.onDiagnostic(console.log); - - try { - const results = await engine.transfer(); - const { destination, engine: engineResults } = results; - - const relativeArchivePath = path.relative(process.cwd(), destination.file.path); - - console.log(`Dataset exported to: ${relativeArchivePath}`); - console.log('The export contains:'); - console.log(` - ${engineResults.schemas?.count ?? 0} schemas`); - console.log(` - ${engineResults.entities?.count ?? 0} entities`); - console.log(` - ${engineResults.links?.count ?? 0} links`); - console.log(` - ${engineResults.assets?.count ?? 0} assets`); - console.log(` - ${engineResults.configuration?.count ?? 0} configs`); - - process.exit(0); - } catch (e) { - console.error('Export process failed.'); - console.error(e); - process.exit(1); - } -}; - -const createSourceProvider = (strapi) => - createLocalStrapiSourceProvider({ - async getStrapi() { - return strapi; - }, - }); - -const createDestinationProvider = (datasetPath) => { - return createLocalFileDestinationProvider({ - file: { path: datasetPath }, - encryption: { enabled: false }, - compression: { enabled: true }, - }); -}; - -const createStrapiInstance = async (logLevel = 'error') => { - const appContext = await compileStrapi(); - const app = createStrapi(appContext); - - app.log.level = logLevel; - return app.load(); -}; - -createDataset().finally(); diff --git a/tests/e2e/cli/scripts/dts-import.js b/tests/e2e/cli/scripts/dts-import.js deleted file mode 100644 index 5d662b2af4..0000000000 --- a/tests/e2e/cli/scripts/dts-import.js +++ /dev/null @@ -1,54 +0,0 @@ -const { resolve } = require('path'); -const { CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } = require('../constants'); -const { - file: { - providers: { createLocalFileSourceProvider }, - }, - strapi: { - providers: { createRemoteStrapiDestinationProvider }, - }, - engine: { createTransferEngine }, -} = require('@strapi/data-transfer'); - -/** - * Reset the DB and import data from a DTS dataset - * This is meant to be used directly from a CLI test - */ -const resetDatabaseAndImportDataFromPath = async (filePath) => { - const source = createSourceProvider(filePath); - const destination = createDestinationProvider(); - - const engine = createTransferEngine(source, destination, { - versionStrategy: 'ignore', - schemaStrategy: 'ignore', - }); - - engine.diagnostics.onDiagnostic(console.log); - - try { - await engine.transfer(); - } catch (e) { - console.error('Import process failed.'); - console.error(e); - process.exit(1); - } -}; - -const createSourceProvider = (filePath) => - createLocalFileSourceProvider({ - file: { path: resolve(filePath) }, - encryption: { enabled: false }, - compression: { enabled: true }, - }); - -const createDestinationProvider = () => { - // TODO: When possible, use the local strapi destination provider instead - // For this we need to wait to have access to a Strapi instance - return createRemoteStrapiDestinationProvider({ - url: new URL(`http://127.0.0.1:${process.env.PORT ?? 1337}/admin`), - auth: { type: 'token', token: CUSTOM_TRANSFER_TOKEN_ACCESS_KEY }, - strategy: 'restore', - }); -}; - -module.exports = { resetDatabaseAndImportDataFromPath }; diff --git a/tests/e2e/cli/scripts/rate-limit.js b/tests/e2e/cli/scripts/rate-limit.js deleted file mode 100644 index ff37bc5ee0..0000000000 --- a/tests/e2e/cli/scripts/rate-limit.js +++ /dev/null @@ -1,6 +0,0 @@ -export async function toggleRateLimiting(page, enabled = true) { - await page.request.fetch('/api/config/ratelimit/enable', { - method: 'POST', - data: { value: enabled }, - }); -} diff --git a/tests/e2e/cli/utils/index.js b/tests/e2e/cli/utils/index.js deleted file mode 100644 index fb34338b0e..0000000000 --- a/tests/e2e/cli/utils/index.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -module.exports = { - fs: require('./fs'), - seed: require('../scripts/dts-import'), - instances: require('./test-app'), - helpers: require('./helpers'), -}; diff --git a/tests/e2e/browser/constants.ts b/tests/e2e/constants.ts similarity index 94% rename from tests/e2e/browser/constants.ts rename to tests/e2e/constants.ts index 74b0a24300..44e7dd9e2c 100644 --- a/tests/e2e/browser/constants.ts +++ b/tests/e2e/constants.ts @@ -1,4 +1,4 @@ -export const { CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } = require('../app-template/src/constants'); +export const { CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } = require('./app-template/src/constants'); // NOTE: anything included here needs to be included in all test datasets exports export const ALLOWED_CONTENT_TYPES = [ diff --git a/tests/e2e/data/with-admin.tar b/tests/e2e/data/with-admin.tar new file mode 100644 index 0000000000..91672da55d Binary files /dev/null and b/tests/e2e/data/with-admin.tar differ diff --git a/tests/e2e/data/without-admin.tar b/tests/e2e/data/without-admin.tar new file mode 100644 index 0000000000..67ee822ffc Binary files /dev/null and b/tests/e2e/data/without-admin.tar differ diff --git a/tests/e2e/browser/tests/admin/admin-auth-sessions.spec.ts b/tests/e2e/tests/admin/admin-auth-sessions.spec.ts similarity index 92% rename from tests/e2e/browser/tests/admin/admin-auth-sessions.spec.ts rename to tests/e2e/tests/admin/admin-auth-sessions.spec.ts index 18f1db871b..f22362fe92 100644 --- a/tests/e2e/browser/tests/admin/admin-auth-sessions.spec.ts +++ b/tests/e2e/tests/admin/admin-auth-sessions.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { TITLE_LOGIN, TITLE_HOME } from '../../constants'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { TITLE_LOGIN, TITLE_HOME } from '../../e2e/constants'; test.describe('Legacy Admin Token Migration', () => { test.beforeEach(async ({ page, context }) => { diff --git a/tests/e2e/browser/tests/admin/api-tokens.spec.ts b/tests/e2e/tests/admin/api-tokens.spec.ts similarity index 94% rename from tests/e2e/browser/tests/admin/api-tokens.spec.ts rename to tests/e2e/tests/admin/api-tokens.spec.ts index aca40d545c..ec2c4b4318 100644 --- a/tests/e2e/browser/tests/admin/api-tokens.spec.ts +++ b/tests/e2e/tests/admin/api-tokens.spec.ts @@ -1,6 +1,6 @@ import { test, expect } from '@playwright/test'; -import { navToHeader } from '../../utils/shared'; -import { sharedSetup } from '../../utils/setup'; +import { navToHeader } from '../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; const createAPIToken = async (page, tokenName, duration, type) => { await navToHeader(page, ['Settings', 'API Tokens', 'Create new API Token'], 'Create API Token'); diff --git a/tests/e2e/browser/tests/admin/ee/home.spec.ts b/tests/e2e/tests/admin/ee/home.spec.ts similarity index 100% rename from tests/e2e/browser/tests/admin/ee/home.spec.ts rename to tests/e2e/tests/admin/ee/home.spec.ts diff --git a/tests/e2e/browser/tests/admin/guided-tour.spec.ts b/tests/e2e/tests/admin/guided-tour.spec.ts similarity index 97% rename from tests/e2e/browser/tests/admin/guided-tour.spec.ts rename to tests/e2e/tests/admin/guided-tour.spec.ts index 951bef29f2..777c247398 100644 --- a/tests/e2e/browser/tests/admin/guided-tour.spec.ts +++ b/tests/e2e/tests/admin/guided-tour.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { sharedSetup } from '../../utils/setup'; -import { STRAPI_GUIDED_TOUR_CONFIG, setGuidedTourLocalStorage } from '../../utils/global-setup'; -import { clickAndWait, describeOnCondition } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; +import { sharedSetup } from '../../../utils/setup'; +import { STRAPI_GUIDED_TOUR_CONFIG, setGuidedTourLocalStorage } from '../../../utils/global-setup'; +import { clickAndWait, describeOnCondition } from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/admin/home-customization.spec.ts b/tests/e2e/tests/admin/home-customization.spec.ts similarity index 94% rename from tests/e2e/browser/tests/admin/home-customization.spec.ts rename to tests/e2e/tests/admin/home-customization.spec.ts index de0c6db5fa..79556db05d 100644 --- a/tests/e2e/browser/tests/admin/home-customization.spec.ts +++ b/tests/e2e/tests/admin/home-customization.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { clickAndWait } from '../../../utils/shared'; test.describe('Homepage Widget Customization', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/admin/home.spec.ts b/tests/e2e/tests/admin/home.spec.ts similarity index 97% rename from tests/e2e/browser/tests/admin/home.spec.ts rename to tests/e2e/tests/admin/home.spec.ts index 9a0694c20b..67036a91f0 100644 --- a/tests/e2e/browser/tests/admin/home.spec.ts +++ b/tests/e2e/tests/admin/home.spec.ts @@ -1,9 +1,9 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, navToHeader } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; -import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../constants'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { clickAndWait, navToHeader } from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; +import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../e2e/constants'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/admin/login.spec.ts b/tests/e2e/tests/admin/login.spec.ts similarity index 95% rename from tests/e2e/browser/tests/admin/login.spec.ts rename to tests/e2e/tests/admin/login.spec.ts index 74eaf778eb..2a7b91e104 100644 --- a/tests/e2e/browser/tests/admin/login.spec.ts +++ b/tests/e2e/tests/admin/login.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { toggleRateLimiting } from '../../utils/rate-limit'; -import { ADMIN_EMAIL_ADDRESS, ADMIN_PASSWORD, TITLE_HOME, TITLE_LOGIN } from '../../constants'; -import { login } from '../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { toggleRateLimiting } from '../../../utils/rate-limit'; +import { ADMIN_EMAIL_ADDRESS, ADMIN_PASSWORD, TITLE_HOME, TITLE_LOGIN } from '../../e2e/constants'; +import { login } from '../../../utils/login'; test.describe('Login', () => { test.beforeEach(async ({ page, context }) => { diff --git a/tests/e2e/browser/tests/admin/logout.spec.ts b/tests/e2e/tests/admin/logout.spec.ts similarity index 82% rename from tests/e2e/browser/tests/admin/logout.spec.ts rename to tests/e2e/tests/admin/logout.spec.ts index 48b8e5f190..d8ce0d2e9b 100644 --- a/tests/e2e/browser/tests/admin/logout.spec.ts +++ b/tests/e2e/tests/admin/logout.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; // eslint-disable-next-line import/extensions -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; test.describe('Log Out', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/admin/signup.spec.ts b/tests/e2e/tests/admin/signup.spec.ts similarity index 94% rename from tests/e2e/browser/tests/admin/signup.spec.ts rename to tests/e2e/tests/admin/signup.spec.ts index 378611a287..412558c7f7 100644 --- a/tests/e2e/browser/tests/admin/signup.spec.ts +++ b/tests/e2e/tests/admin/signup.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { ADMIN_EMAIL_ADDRESS, TITLE_HOME } from '../../constants'; +import { ADMIN_EMAIL_ADDRESS, TITLE_HOME } from '../../e2e/constants'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { fillValidSignUpForm } from '../../utils/signup'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { fillValidSignUpForm } from '../../../utils/signup'; test.describe('Sign Up', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/admin/transfer-tokens.spec.ts b/tests/e2e/tests/admin/transfer-tokens.spec.ts similarity index 92% rename from tests/e2e/browser/tests/admin/transfer-tokens.spec.ts rename to tests/e2e/tests/admin/transfer-tokens.spec.ts index 3bcd62a0a5..4e8044967d 100644 --- a/tests/e2e/browser/tests/admin/transfer-tokens.spec.ts +++ b/tests/e2e/tests/admin/transfer-tokens.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { navToHeader } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { navToHeader } from '../../../utils/shared'; const createTransferToken = async (page, tokenName, duration, type) => { await navToHeader(page, ['Settings', 'Transfer Tokens'], 'Transfer Tokens'); diff --git a/tests/e2e/browser/tests/content-manager/blocks.spec.ts b/tests/e2e/tests/content-manager/blocks.spec.ts similarity index 92% rename from tests/e2e/browser/tests/content-manager/blocks.spec.ts rename to tests/e2e/tests/content-manager/blocks.spec.ts index 17014c7ddd..c426b9abbd 100644 --- a/tests/e2e/browser/tests/content-manager/blocks.spec.ts +++ b/tests/e2e/tests/content-manager/blocks.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { navToHeader } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { navToHeader } from '../../../utils/shared'; const EDIT_URL = /\/admin\/content-manager\/single-types\/api::homepage.homepage(\?.*)?/; diff --git a/tests/e2e/browser/tests/content-manager/bulk-actions.spec.ts b/tests/e2e/tests/content-manager/bulk-actions.spec.ts similarity index 84% rename from tests/e2e/browser/tests/content-manager/bulk-actions.spec.ts rename to tests/e2e/tests/content-manager/bulk-actions.spec.ts index 07bee8d18a..1f84c3ff68 100644 --- a/tests/e2e/browser/tests/content-manager/bulk-actions.spec.ts +++ b/tests/e2e/tests/content-manager/bulk-actions.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { clickAndWait, findAndClose, navToHeader } from '../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { clickAndWait, findAndClose, navToHeader } from '../../../utils/shared'; test.describe('Bulk actions', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/cloning.spec.ts b/tests/e2e/tests/content-manager/cloning.spec.ts similarity index 97% rename from tests/e2e/browser/tests/content-manager/cloning.spec.ts rename to tests/e2e/tests/content-manager/cloning.spec.ts index 07c231b8a3..e3816d7d4b 100644 --- a/tests/e2e/browser/tests/content-manager/cloning.spec.ts +++ b/tests/e2e/tests/content-manager/cloning.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { findAndClose, navToHeader } from '../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { findAndClose, navToHeader } from '../../../utils/shared'; const EDIT_URL_AUTHOR = /\/admin\/content-manager\/collection-types\/api::author.author\/[^/]+(\?.*)?/; diff --git a/tests/e2e/browser/tests/content-manager/conditional-fields/boolean-conditional-many-to-many-relation-visibility.spec.ts b/tests/e2e/tests/content-manager/conditional-fields/boolean-conditional-many-to-many-relation-visibility.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/conditional-fields/boolean-conditional-many-to-many-relation-visibility.spec.ts rename to tests/e2e/tests/content-manager/conditional-fields/boolean-conditional-many-to-many-relation-visibility.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/conditional-fields/boolean-conditional-select-relation.spec.ts b/tests/e2e/tests/content-manager/conditional-fields/boolean-conditional-select-relation.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/conditional-fields/boolean-conditional-select-relation.spec.ts rename to tests/e2e/tests/content-manager/conditional-fields/boolean-conditional-select-relation.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/conditional-fields/boolean-conditional-text-field-visibility.spec.ts b/tests/e2e/tests/content-manager/conditional-fields/boolean-conditional-text-field-visibility.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/conditional-fields/boolean-conditional-text-field-visibility.spec.ts rename to tests/e2e/tests/content-manager/conditional-fields/boolean-conditional-text-field-visibility.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/conditional-fields/enum-conditional-text-field-visibility.spec.ts b/tests/e2e/tests/content-manager/conditional-fields/enum-conditional-text-field-visibility.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/conditional-fields/enum-conditional-text-field-visibility.spec.ts rename to tests/e2e/tests/content-manager/conditional-fields/enum-conditional-text-field-visibility.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/create-content.spec.ts b/tests/e2e/tests/content-manager/create-content.spec.ts similarity index 96% rename from tests/e2e/browser/tests/content-manager/create-content.spec.ts rename to tests/e2e/tests/content-manager/create-content.spec.ts index aaa4096ad2..6a2a143205 100644 --- a/tests/e2e/browser/tests/content-manager/create-content.spec.ts +++ b/tests/e2e/tests/content-manager/create-content.spec.ts @@ -5,10 +5,10 @@ import { findAndClose, isElementBefore, navToHeader, -} from '../../utils/shared'; -import { createContent, FieldValue, verifyFields } from '../../utils/content-creation'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; +} from '../../../utils/shared'; +import { createContent, FieldValue, verifyFields } from '../../../utils/content-creation'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; test.describe('Adding content', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/date.spec.ts b/tests/e2e/tests/content-manager/date.spec.ts similarity index 91% rename from tests/e2e/browser/tests/content-manager/date.spec.ts rename to tests/e2e/tests/content-manager/date.spec.ts index f252129236..2168e0d5b7 100644 --- a/tests/e2e/browser/tests/content-manager/date.spec.ts +++ b/tests/e2e/tests/content-manager/date.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { clickAndWait } from '../../utils/shared'; -import { createContent } from '../../utils/content-creation'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; +import { clickAndWait } from '../../../utils/shared'; +import { createContent } from '../../../utils/content-creation'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; // Helper to get date in MM/DD/YYYY format consistently function toMMDDYYYY(date: Date) { diff --git a/tests/e2e/browser/tests/content-manager/decimal-field-hint.spec.ts b/tests/e2e/tests/content-manager/decimal-field-hint.spec.ts similarity index 84% rename from tests/e2e/browser/tests/content-manager/decimal-field-hint.spec.ts rename to tests/e2e/tests/content-manager/decimal-field-hint.spec.ts index a8c4fec3ee..10ef3509fb 100644 --- a/tests/e2e/browser/tests/content-manager/decimal-field-hint.spec.ts +++ b/tests/e2e/tests/content-manager/decimal-field-hint.spec.ts @@ -1,11 +1,11 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { navToHeader, clickAndWait } from '../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; import { addAttributesToContentType, removeAttributeFromComponent, -} from '../../utils/content-types'; +} from '../../../utils/content-types'; test.describe('Decimal field hint with min/max values', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/edit-view/collection-type-edit-view-errors.spec.ts b/tests/e2e/tests/content-manager/edit-view/collection-type-edit-view-errors.spec.ts similarity index 99% rename from tests/e2e/browser/tests/content-manager/edit-view/collection-type-edit-view-errors.spec.ts rename to tests/e2e/tests/content-manager/edit-view/collection-type-edit-view-errors.spec.ts index 01bbcab32c..c8cef1e3bd 100644 --- a/tests/e2e/browser/tests/content-manager/edit-view/collection-type-edit-view-errors.spec.ts +++ b/tests/e2e/tests/content-manager/edit-view/collection-type-edit-view-errors.spec.ts @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; import { login } from '../../../utils/login'; import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; import { clickAndWait, findAndClose, navToHeader } from '../../../utils/shared'; -import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../../constants'; +import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../../e2e/constants'; test.describe('Edit View', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/edit-view/collection-type-edit-view.spec.ts b/tests/e2e/tests/content-manager/edit-view/collection-type-edit-view.spec.ts similarity index 99% rename from tests/e2e/browser/tests/content-manager/edit-view/collection-type-edit-view.spec.ts rename to tests/e2e/tests/content-manager/edit-view/collection-type-edit-view.spec.ts index e2ee3fa8b9..fd16596b26 100644 --- a/tests/e2e/browser/tests/content-manager/edit-view/collection-type-edit-view.spec.ts +++ b/tests/e2e/tests/content-manager/edit-view/collection-type-edit-view.spec.ts @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; import { login } from '../../../utils/login'; import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; import { clickAndWait, findAndClose, navToHeader } from '../../../utils/shared'; -import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../../constants'; +import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../../e2e/constants'; test.describe('Edit View', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/edit-view/enumeration-fields.spec.ts b/tests/e2e/tests/content-manager/edit-view/enumeration-fields.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/edit-view/enumeration-fields.spec.ts rename to tests/e2e/tests/content-manager/edit-view/enumeration-fields.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/edit-view/single-type-edit-view.spec.ts b/tests/e2e/tests/content-manager/edit-view/single-type-edit-view.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/edit-view/single-type-edit-view.spec.ts rename to tests/e2e/tests/content-manager/edit-view/single-type-edit-view.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/history.spec.ts b/tests/e2e/tests/content-manager/history.spec.ts similarity index 98% rename from tests/e2e/browser/tests/content-manager/history.spec.ts rename to tests/e2e/tests/content-manager/history.spec.ts index 7df283c83d..e9111add16 100644 --- a/tests/e2e/browser/tests/content-manager/history.spec.ts +++ b/tests/e2e/tests/content-manager/history.spec.ts @@ -1,8 +1,13 @@ import { test, expect, Page } from '@playwright/test'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; -import { resetFiles } from '../../utils/file-reset'; -import { waitForRestart } from '../../utils/restart'; -import { sharedSetup } from '../../utils/setup'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; +import { resetFiles } from '../../../utils/file-reset'; +import { waitForRestart } from '../../../utils/restart'; +import { sharedSetup } from '../../../utils/setup'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/content-manager/home-widgets.spec.ts b/tests/e2e/tests/content-manager/home-widgets.spec.ts similarity index 97% rename from tests/e2e/browser/tests/content-manager/home-widgets.spec.ts rename to tests/e2e/tests/content-manager/home-widgets.spec.ts index d4e60fe44c..293f6f22bd 100644 --- a/tests/e2e/browser/tests/content-manager/home-widgets.spec.ts +++ b/tests/e2e/tests/content-manager/home-widgets.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, findAndClose, navToHeader } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { clickAndWait, findAndClose, navToHeader } from '../../../utils/shared'; test.describe('Homepage - Content Manager Widgets', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/listview.spec.ts b/tests/e2e/tests/content-manager/listview.spec.ts similarity index 98% rename from tests/e2e/browser/tests/content-manager/listview.spec.ts rename to tests/e2e/tests/content-manager/listview.spec.ts index 8ac315125e..ae00f47dc7 100644 --- a/tests/e2e/browser/tests/content-manager/listview.spec.ts +++ b/tests/e2e/tests/content-manager/listview.spec.ts @@ -1,6 +1,6 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; test.describe('List View', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/preview.spec.ts b/tests/e2e/tests/content-manager/preview.spec.ts similarity index 97% rename from tests/e2e/browser/tests/content-manager/preview.spec.ts rename to tests/e2e/tests/content-manager/preview.spec.ts index deae666edd..a4dcba0f34 100644 --- a/tests/e2e/browser/tests/content-manager/preview.spec.ts +++ b/tests/e2e/tests/content-manager/preview.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, describeOnCondition, findAndClose } from '../../utils/shared'; -import { resetFiles } from '../../utils/file-reset'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { clickAndWait, describeOnCondition, findAndClose } from '../../../utils/shared'; +import { resetFiles } from '../../../utils/file-reset'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-and-publish.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-and-publish.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-and-publish.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-and-publish.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-and-save.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-and-save.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-and-save.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-and-save.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-editor.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-editor.spec.ts similarity index 98% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-editor.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-editor.spec.ts index 0a01d80b5f..32e6bedee7 100644 --- a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-editor.spec.ts +++ b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-editor.spec.ts @@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test'; import { login } from '../../../utils/login'; import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; import { clickAndWait } from '../../../utils/shared'; -import { AUTHOR_EMAIL_ADDRESS, AUTHOR_PASSWORD } from '../../../constants'; +import { AUTHOR_EMAIL_ADDRESS, AUTHOR_PASSWORD } from '../../../e2e/constants'; test.describe('Relations on the fly - Create a Relation', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-in-component-and-save.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-in-component-and-save.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-in-component-and-save.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-in-component-and-save.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-in-new-component-and-save.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-in-new-component-and-save.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation-in-new-component-and-save.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/create-relation-in-new-component-and-save.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/create-relation.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/create-relation.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/create-relation.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/relations-on-the-fly/edit-relation.spec.ts b/tests/e2e/tests/content-manager/relations-on-the-fly/edit-relation.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-manager/relations-on-the-fly/edit-relation.spec.ts rename to tests/e2e/tests/content-manager/relations-on-the-fly/edit-relation.spec.ts diff --git a/tests/e2e/browser/tests/content-manager/uniqueness.spec.ts b/tests/e2e/tests/content-manager/uniqueness.spec.ts similarity index 97% rename from tests/e2e/browser/tests/content-manager/uniqueness.spec.ts rename to tests/e2e/tests/content-manager/uniqueness.spec.ts index bd31947b62..df58a6cd52 100644 --- a/tests/e2e/browser/tests/content-manager/uniqueness.spec.ts +++ b/tests/e2e/tests/content-manager/uniqueness.spec.ts @@ -1,7 +1,7 @@ import { test, expect, Page } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { findAndClose, clickAndWait } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { findAndClose, clickAndWait } from '../../../utils/shared'; type Field = { name: string; diff --git a/tests/e2e/browser/tests/content-releases/document-status.spec.ts b/tests/e2e/tests/content-releases/document-status.spec.ts similarity index 89% rename from tests/e2e/browser/tests/content-releases/document-status.spec.ts rename to tests/e2e/tests/content-releases/document-status.spec.ts index 292bbbb375..7b4164a2ff 100644 --- a/tests/e2e/browser/tests/content-releases/document-status.spec.ts +++ b/tests/e2e/tests/content-releases/document-status.spec.ts @@ -1,8 +1,13 @@ import { test, expect } from '@playwright/test'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; -import { resetFiles } from '../../utils/file-reset'; -import { sharedSetup } from '../../utils/setup'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; +import { resetFiles } from '../../../utils/file-reset'; +import { sharedSetup } from '../../../utils/setup'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/content-releases/home-widgets.spec.ts b/tests/e2e/tests/content-releases/home-widgets.spec.ts similarity index 93% rename from tests/e2e/browser/tests/content-releases/home-widgets.spec.ts rename to tests/e2e/tests/content-releases/home-widgets.spec.ts index 0d541773e1..225a6760d8 100644 --- a/tests/e2e/browser/tests/content-releases/home-widgets.spec.ts +++ b/tests/e2e/tests/content-releases/home-widgets.spec.ts @@ -1,7 +1,12 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/content-releases/release-details-page.spec.ts b/tests/e2e/tests/content-releases/release-details-page.spec.ts similarity index 97% rename from tests/e2e/browser/tests/content-releases/release-details-page.spec.ts rename to tests/e2e/tests/content-releases/release-details-page.spec.ts index dd67b35e22..6771a3e144 100644 --- a/tests/e2e/browser/tests/content-releases/release-details-page.spec.ts +++ b/tests/e2e/tests/content-releases/release-details-page.spec.ts @@ -1,8 +1,8 @@ import { test, expect, type Page } from '@playwright/test'; -import { clickAndWait, describeOnCondition, navToHeader } from '../../utils/shared'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { findAndClose } from '../../utils/shared'; +import { clickAndWait, describeOnCondition, navToHeader } from '../../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { findAndClose } from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; const releaseName = 'Trent Crimm: The Independent'; diff --git a/tests/e2e/browser/tests/content-releases/releases-page.spec.ts b/tests/e2e/tests/content-releases/releases-page.spec.ts similarity index 96% rename from tests/e2e/browser/tests/content-releases/releases-page.spec.ts rename to tests/e2e/tests/content-releases/releases-page.spec.ts index b05a452d8b..83606c6625 100644 --- a/tests/e2e/browser/tests/content-releases/releases-page.spec.ts +++ b/tests/e2e/tests/content-releases/releases-page.spec.ts @@ -1,8 +1,13 @@ import { test, expect } from '@playwright/test'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; -import { resetFiles } from '../../utils/file-reset'; -import { sharedSetup } from '../../utils/setup'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; +import { resetFiles } from '../../../utils/file-reset'; +import { sharedSetup } from '../../../utils/setup'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/content-type-builder/collection-type/create-collection-type.spec.ts b/tests/e2e/tests/content-type-builder/collection-type/create-collection-type.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/collection-type/create-collection-type.spec.ts rename to tests/e2e/tests/content-type-builder/collection-type/create-collection-type.spec.ts diff --git a/tests/e2e/browser/tests/content-type-builder/collection-type/edit-collection-type.spec.ts b/tests/e2e/tests/content-type-builder/collection-type/edit-collection-type.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/collection-type/edit-collection-type.spec.ts rename to tests/e2e/tests/content-type-builder/collection-type/edit-collection-type.spec.ts diff --git a/tests/e2e/browser/tests/content-type-builder/collection-type/uid-generation.spec.ts b/tests/e2e/tests/content-type-builder/collection-type/uid-generation.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/collection-type/uid-generation.spec.ts rename to tests/e2e/tests/content-type-builder/collection-type/uid-generation.spec.ts diff --git a/tests/e2e/browser/tests/content-type-builder/components/create-components.spec.ts b/tests/e2e/tests/content-type-builder/components/create-components.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/components/create-components.spec.ts rename to tests/e2e/tests/content-type-builder/components/create-components.spec.ts diff --git a/tests/e2e/browser/tests/content-type-builder/components/edit-components.spec.ts b/tests/e2e/tests/content-type-builder/components/edit-components.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/components/edit-components.spec.ts rename to tests/e2e/tests/content-type-builder/components/edit-components.spec.ts diff --git a/tests/e2e/browser/tests/content-type-builder/ctb-edit-view.spec.ts b/tests/e2e/tests/content-type-builder/ctb-edit-view.spec.ts similarity index 84% rename from tests/e2e/browser/tests/content-type-builder/ctb-edit-view.spec.ts rename to tests/e2e/tests/content-type-builder/ctb-edit-view.spec.ts index dd413f18df..7c246f5852 100644 --- a/tests/e2e/browser/tests/content-type-builder/ctb-edit-view.spec.ts +++ b/tests/e2e/tests/content-type-builder/ctb-edit-view.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { navToHeader } from '../../utils/shared'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { navToHeader } from '../../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; test.describe('Edit View CTB', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/content-type-builder/guided-tour.spec.ts b/tests/e2e/tests/content-type-builder/guided-tour.spec.ts similarity index 90% rename from tests/e2e/browser/tests/content-type-builder/guided-tour.spec.ts rename to tests/e2e/tests/content-type-builder/guided-tour.spec.ts index 8535c74f23..8239583a64 100644 --- a/tests/e2e/browser/tests/content-type-builder/guided-tour.spec.ts +++ b/tests/e2e/tests/content-type-builder/guided-tour.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { sharedSetup } from '../../utils/setup'; -import { STRAPI_GUIDED_TOUR_CONFIG, setGuidedTourLocalStorage } from '../../utils/global-setup'; -import { clickAndWait, describeOnCondition } from '../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { STRAPI_GUIDED_TOUR_CONFIG, setGuidedTourLocalStorage } from '../../../utils/global-setup'; +import { clickAndWait, describeOnCondition } from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/content-type-builder/single-type/create-single-type.spec.ts b/tests/e2e/tests/content-type-builder/single-type/create-single-type.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/single-type/create-single-type.spec.ts rename to tests/e2e/tests/content-type-builder/single-type/create-single-type.spec.ts diff --git a/tests/e2e/browser/tests/content-type-builder/single-type/edit-single-type.spec.ts b/tests/e2e/tests/content-type-builder/single-type/edit-single-type.spec.ts similarity index 100% rename from tests/e2e/browser/tests/content-type-builder/single-type/edit-single-type.spec.ts rename to tests/e2e/tests/content-type-builder/single-type/edit-single-type.spec.ts diff --git a/tests/e2e/browser/tests/i18n/bulk-locale-modal.spec.ts b/tests/e2e/tests/i18n/bulk-locale-modal.spec.ts similarity index 88% rename from tests/e2e/browser/tests/i18n/bulk-locale-modal.spec.ts rename to tests/e2e/tests/i18n/bulk-locale-modal.spec.ts index fd55680d62..4d562a0bab 100644 --- a/tests/e2e/browser/tests/i18n/bulk-locale-modal.spec.ts +++ b/tests/e2e/tests/i18n/bulk-locale-modal.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { findAndClose, navToHeader } from '../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { findAndClose, navToHeader } from '../../../utils/shared'; test.describe('Bulk locale actions', () => { test.describe.configure({ timeout: 500000 }); diff --git a/tests/e2e/browser/tests/i18n/create-edit.spec.ts b/tests/e2e/tests/i18n/create-edit.spec.ts similarity index 96% rename from tests/e2e/browser/tests/i18n/create-edit.spec.ts rename to tests/e2e/tests/i18n/create-edit.spec.ts index fa7c7d5ebe..64f17887c3 100644 --- a/tests/e2e/browser/tests/i18n/create-edit.spec.ts +++ b/tests/e2e/tests/i18n/create-edit.spec.ts @@ -1,10 +1,10 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { clickAndWait, findAndClose, navToHeader } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; -import { resetFiles } from '../../utils/file-reset'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { clickAndWait, findAndClose, navToHeader } from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; +import { resetFiles } from '../../../utils/file-reset'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; test.describe('Create and Edit Operations', () => { test.describe.configure({ timeout: 500000 }); diff --git a/tests/e2e/browser/tests/i18n/editview.spec.ts b/tests/e2e/tests/i18n/editview.spec.ts similarity index 98% rename from tests/e2e/browser/tests/i18n/editview.spec.ts rename to tests/e2e/tests/i18n/editview.spec.ts index c50ebcfbed..650fc3a4df 100644 --- a/tests/e2e/browser/tests/i18n/editview.spec.ts +++ b/tests/e2e/tests/i18n/editview.spec.ts @@ -1,10 +1,15 @@ import { test, expect } from '@playwright/test'; -import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../constants'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; +import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../e2e/constants'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; interface ValidationType { field: string; diff --git a/tests/e2e/browser/tests/i18n/listview.spec.ts b/tests/e2e/tests/i18n/listview.spec.ts similarity index 97% rename from tests/e2e/browser/tests/i18n/listview.spec.ts rename to tests/e2e/tests/i18n/listview.spec.ts index 17ce46005a..346f845dc5 100644 --- a/tests/e2e/browser/tests/i18n/listview.spec.ts +++ b/tests/e2e/tests/i18n/listview.spec.ts @@ -1,6 +1,6 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; test.describe('List view', () => { test.beforeEach(async ({ page }) => { diff --git a/tests/e2e/browser/tests/i18n/localized-fields.spec.ts b/tests/e2e/tests/i18n/localized-fields.spec.ts similarity index 97% rename from tests/e2e/browser/tests/i18n/localized-fields.spec.ts rename to tests/e2e/tests/i18n/localized-fields.spec.ts index 409e7b24cc..a8e058f17c 100644 --- a/tests/e2e/browser/tests/i18n/localized-fields.spec.ts +++ b/tests/e2e/tests/i18n/localized-fields.spec.ts @@ -1,10 +1,10 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { navToHeader } from '../../utils/shared'; -import { findAndClose } from '../../utils/shared'; -import { resetFiles } from '../../utils/file-reset'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { navToHeader } from '../../../utils/shared'; +import { findAndClose } from '../../../utils/shared'; +import { resetFiles } from '../../../utils/file-reset'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; test.describe('Locale Isolation', () => { test.describe.configure({ timeout: 500000 }); diff --git a/tests/e2e/browser/tests/i18n/permissions.spec.ts b/tests/e2e/tests/i18n/permissions.spec.ts similarity index 92% rename from tests/e2e/browser/tests/i18n/permissions.spec.ts rename to tests/e2e/tests/i18n/permissions.spec.ts index 0e485b4888..525b2b2d32 100644 --- a/tests/e2e/browser/tests/i18n/permissions.spec.ts +++ b/tests/e2e/tests/i18n/permissions.spec.ts @@ -1,11 +1,11 @@ import { test, expect } from '@playwright/test'; -import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../constants'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { clickAndWait, findAndClose, navToHeader } from '../../utils/shared'; -import { waitForRestart } from '../../utils/restart'; -import { resetFiles } from '../../utils/file-reset'; +import { EDITOR_EMAIL_ADDRESS, EDITOR_PASSWORD } from '../../e2e/constants'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { clickAndWait, findAndClose, navToHeader } from '../../../utils/shared'; +import { waitForRestart } from '../../../utils/restart'; +import { resetFiles } from '../../../utils/file-reset'; test.describe('Locale Permissions', () => { test.describe.configure({ timeout: 500000 }); diff --git a/tests/e2e/browser/tests/i18n/settings.spec.ts b/tests/e2e/tests/i18n/settings.spec.ts similarity index 97% rename from tests/e2e/browser/tests/i18n/settings.spec.ts rename to tests/e2e/tests/i18n/settings.spec.ts index a73f5495f6..e02261db76 100644 --- a/tests/e2e/browser/tests/i18n/settings.spec.ts +++ b/tests/e2e/tests/i18n/settings.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { prunePermissions } from '../../scripts/endpoints'; -import { findAndClose, navToHeader } from '../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { prunePermissions } from '../../../scripts/endpoints'; +import { findAndClose, navToHeader } from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/review-workflows/content-manager.spec.ts b/tests/e2e/tests/review-workflows/content-manager.spec.ts similarity index 97% rename from tests/e2e/browser/tests/review-workflows/content-manager.spec.ts rename to tests/e2e/tests/review-workflows/content-manager.spec.ts index b5580b000d..b4d03cebde 100644 --- a/tests/e2e/browser/tests/review-workflows/content-manager.spec.ts +++ b/tests/e2e/tests/review-workflows/content-manager.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, describeOnCondition, findAndClose } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { clickAndWait, describeOnCondition, findAndClose } from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/review-workflows/home.spec.ts b/tests/e2e/tests/review-workflows/home.spec.ts similarity index 86% rename from tests/e2e/browser/tests/review-workflows/home.spec.ts rename to tests/e2e/tests/review-workflows/home.spec.ts index 67d05d0977..04599e8143 100644 --- a/tests/e2e/browser/tests/review-workflows/home.spec.ts +++ b/tests/e2e/tests/review-workflows/home.spec.ts @@ -1,7 +1,12 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/review-workflows/settings.spec.ts b/tests/e2e/tests/review-workflows/settings.spec.ts similarity index 96% rename from tests/e2e/browser/tests/review-workflows/settings.spec.ts rename to tests/e2e/tests/review-workflows/settings.spec.ts index 0526b90963..67b8bc610d 100644 --- a/tests/e2e/browser/tests/review-workflows/settings.spec.ts +++ b/tests/e2e/tests/review-workflows/settings.spec.ts @@ -1,7 +1,12 @@ import { test, expect } from '@playwright/test'; -import { login } from '../../utils/login'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { clickAndWait, describeOnCondition, findAndClose, navToHeader } from '../../utils/shared'; +import { login } from '../../../utils/login'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { + clickAndWait, + describeOnCondition, + findAndClose, + navToHeader, +} from '../../../utils/shared'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/tests/search/content-type.spec.ts b/tests/e2e/tests/search/content-type.spec.ts similarity index 92% rename from tests/e2e/browser/tests/search/content-type.spec.ts rename to tests/e2e/tests/search/content-type.spec.ts index 37798bedc3..39e44babf9 100644 --- a/tests/e2e/browser/tests/search/content-type.spec.ts +++ b/tests/e2e/tests/search/content-type.spec.ts @@ -1,8 +1,8 @@ import { test, expect } from '@playwright/test'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; -import { login } from '../../utils/login'; -import { clickAndWait, navToHeader } from '../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { clickAndWait, navToHeader } from '../../../utils/shared'; function createSearchTest(testFunction, description, searchTerm) { testFunction(description, async ({ page }) => { diff --git a/tests/e2e/browser/tests/settings/rbac/actions/assign-role-to-user.spec.ts b/tests/e2e/tests/settings/rbac/actions/assign-role-to-user.spec.ts similarity index 94% rename from tests/e2e/browser/tests/settings/rbac/actions/assign-role-to-user.spec.ts rename to tests/e2e/tests/settings/rbac/actions/assign-role-to-user.spec.ts index 2b211520d5..93acf420ee 100644 --- a/tests/e2e/browser/tests/settings/rbac/actions/assign-role-to-user.spec.ts +++ b/tests/e2e/tests/settings/rbac/actions/assign-role-to-user.spec.ts @@ -1,7 +1,7 @@ import { test, expect, type Page } from '@playwright/test'; -import { sharedSetup } from '../../../../utils/setup'; -import { navToHeader, clickAndWait } from '../../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; // Constants for the created role const TARGET_USER = { firstName: 'Editor', lastName: 'Testing' }; diff --git a/tests/e2e/browser/tests/settings/rbac/actions/create-role.spec.ts b/tests/e2e/tests/settings/rbac/actions/create-role.spec.ts similarity index 94% rename from tests/e2e/browser/tests/settings/rbac/actions/create-role.spec.ts rename to tests/e2e/tests/settings/rbac/actions/create-role.spec.ts index 42c9831b71..a6cb7fd301 100644 --- a/tests/e2e/browser/tests/settings/rbac/actions/create-role.spec.ts +++ b/tests/e2e/tests/settings/rbac/actions/create-role.spec.ts @@ -1,7 +1,7 @@ import { test, expect, type Page } from '@playwright/test'; -import { sharedSetup } from '../../../../utils/setup'; -import { navToHeader, clickAndWait } from '../../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; // Constants for the created role const NEW_ROLE = { name: 'Publisher', description: 'Role with publishing capabilities' }; diff --git a/tests/e2e/browser/tests/settings/rbac/actions/delete-role.spec.ts b/tests/e2e/tests/settings/rbac/actions/delete-role.spec.ts similarity index 93% rename from tests/e2e/browser/tests/settings/rbac/actions/delete-role.spec.ts rename to tests/e2e/tests/settings/rbac/actions/delete-role.spec.ts index 6dad4636ce..73d6f112bf 100644 --- a/tests/e2e/browser/tests/settings/rbac/actions/delete-role.spec.ts +++ b/tests/e2e/tests/settings/rbac/actions/delete-role.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { sharedSetup } from '../../../../utils/setup'; -import { navToHeader, clickAndWait } from '../../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; test.describe('RBAC - Delete Roles', () => { // Runs before each test diff --git a/tests/e2e/browser/tests/settings/rbac/actions/edit-role.spec.ts b/tests/e2e/tests/settings/rbac/actions/edit-role.spec.ts similarity index 95% rename from tests/e2e/browser/tests/settings/rbac/actions/edit-role.spec.ts rename to tests/e2e/tests/settings/rbac/actions/edit-role.spec.ts index faa81ec627..00a03e3c71 100644 --- a/tests/e2e/browser/tests/settings/rbac/actions/edit-role.spec.ts +++ b/tests/e2e/tests/settings/rbac/actions/edit-role.spec.ts @@ -1,7 +1,7 @@ import { test, expect, type Page } from '@playwright/test'; -import { sharedSetup } from '../../../../utils/setup'; -import { navToHeader, clickAndWait } from '../../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; // Constants for the edited role const EDITED_ROLE = { name: 'Contractor', description: 'Role with contractor capabilities' }; diff --git a/tests/e2e/browser/tests/settings/rbac/actions/see-role.spec.ts b/tests/e2e/tests/settings/rbac/actions/see-role.spec.ts similarity index 90% rename from tests/e2e/browser/tests/settings/rbac/actions/see-role.spec.ts rename to tests/e2e/tests/settings/rbac/actions/see-role.spec.ts index 2ea8ac9b03..aa1e885f78 100644 --- a/tests/e2e/browser/tests/settings/rbac/actions/see-role.spec.ts +++ b/tests/e2e/tests/settings/rbac/actions/see-role.spec.ts @@ -1,7 +1,7 @@ import { test, expect } from '@playwright/test'; -import { sharedSetup } from '../../../../utils/setup'; -import { navToHeader, clickAndWait } from '../../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; test.describe('RBAC - See Roles', () => { // Runs before each test diff --git a/tests/e2e/browser/tests/settings/rbac/readme.md b/tests/e2e/tests/settings/rbac/readme.md similarity index 100% rename from tests/e2e/browser/tests/settings/rbac/readme.md rename to tests/e2e/tests/settings/rbac/readme.md diff --git a/tests/e2e/browser/tests/settings/rbac/scenarios/create-new-role.scenario.spec.ts b/tests/e2e/tests/settings/rbac/scenarios/create-new-role.scenario.spec.ts similarity index 97% rename from tests/e2e/browser/tests/settings/rbac/scenarios/create-new-role.scenario.spec.ts rename to tests/e2e/tests/settings/rbac/scenarios/create-new-role.scenario.spec.ts index 05dfb40f7c..32fb069b42 100644 --- a/tests/e2e/browser/tests/settings/rbac/scenarios/create-new-role.scenario.spec.ts +++ b/tests/e2e/tests/settings/rbac/scenarios/create-new-role.scenario.spec.ts @@ -1,7 +1,7 @@ import { test, expect, type Page, type Locator } from '@playwright/test'; -import { sharedSetup } from '../../../../utils/setup'; -import { navToHeader, clickAndWait } from '../../../../utils/shared'; +import { sharedSetup } from '../../../utils/setup'; +import { navToHeader, clickAndWait } from '../../../utils/shared'; // Constants for the scenario const OLD_ROLE = { name: 'Editor' }; diff --git a/tests/e2e/browser/tests/settings/smoke-test.spec.ts b/tests/e2e/tests/settings/smoke-test.spec.ts similarity index 91% rename from tests/e2e/browser/tests/settings/smoke-test.spec.ts rename to tests/e2e/tests/settings/smoke-test.spec.ts index 01dcaa5606..4459c9f416 100644 --- a/tests/e2e/browser/tests/settings/smoke-test.spec.ts +++ b/tests/e2e/tests/settings/smoke-test.spec.ts @@ -1,8 +1,8 @@ import { test } from '@playwright/test'; -import { login } from '../../utils/login'; -import { describeOnCondition, navToHeader } from '../../utils/shared'; -import { resetDatabaseAndImportDataFromPath } from '../../utils/dts-import'; +import { login } from '../../../utils/login'; +import { describeOnCondition, navToHeader } from '../../../utils/shared'; +import { resetDatabaseAndImportDataFromPath } from '../../../utils/dts-import'; const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; diff --git a/tests/e2e/browser/playwright-storage-state.json b/tests/playwright-storage-state.json similarity index 100% rename from tests/e2e/browser/playwright-storage-state.json rename to tests/playwright-storage-state.json diff --git a/tests/scripts/run-cli-tests.js b/tests/scripts/run-cli-tests.js index 54955770f8..aa87e28f71 100644 --- a/tests/scripts/run-cli-tests.js +++ b/tests/scripts/run-cli-tests.js @@ -1,16 +1,20 @@ 'use strict'; const path = require('path'); -const execa = require('execa'); const fs = require('node:fs/promises'); const yargs = require('yargs'); const chalk = require('chalk'); -const { cleanTestApp, generateTestApp } = require('../helpers/test-app'); +const { + loadDomainConfigs, + calculateTestAppsRequired, + runCliTests, +} = require('../utils/runners/cli-runner'); +const { publishYalc, setupTestApps, getCurrentTestApps } = require('../utils/runners/shared-setup'); const cwd = path.resolve(__dirname, '../..'); const testAppDirectory = path.join(cwd, 'test-apps', 'cli'); -const testRoot = path.join(cwd, 'tests', 'e2e', 'cli'); +const testRoot = path.join(cwd, 'tests', 'cli'); const testsDir = path.join(testRoot, 'tests'); const templateDir = path.join(cwd, 'tests', 'e2e', 'app-template'); @@ -59,41 +63,14 @@ yargs * Publishing all packages to the yalc store */ console.log('Running yalc...'); - await execa('node', [path.join(__dirname, '../..', 'scripts', 'yalc-publish.js')]); + await publishYalc(cwd); console.log('Complete'); - const loadDomainConfigs = async (domain) => { - try { - const configPath = path.join(testsDir, domain, 'config.js'); - await fs.access(configPath); - // Import config.js and call it as a function - const config = require(configPath); - if (typeof config === 'function') { - return await config(argv); - } - return config; - } catch (e) { - // use default config - return { - testApps: 1, - }; - } - }; + // Load domain configs + const domainConfigs = await loadDomainConfigs(testsDir, domains, argv); - // Load the domain configs into an object with keys of the name of the test domain - const domainConfigs = {}; - await Promise.all( - domains.map(async (domain) => { - domainConfigs[domain] = await loadDomainConfigs(domain); - }) - ); - - // Determine the number of simultaneous test apps we need by taking the concurrency number of highest testApps requested from config - const testAppsRequired = Object.entries(domainConfigs) - .map(([, value]) => value.testApps) // Extract testApps values from config - .sort((a, b) => b - a) // Sort in descending order - .slice(0, concurrency) // Take the top X values - .reduce((acc, value) => acc + value, 0); // Sum up the values + // Determine the number of test apps required + const testAppsRequired = calculateTestAppsRequired(domainConfigs, concurrency); if (testAppsRequired === 0) { throw new Error('No test apps to spawn'); @@ -103,69 +80,21 @@ yargs path.join(testAppDirectory, `test-app-${i}`) ); - let currentTestApps = []; - - try { - currentTestApps = await fs - .readdir(testAppDirectory) - .then((paths) => paths.map((appPath) => path.join(testAppDirectory, appPath))); - } catch (err) { - // no test apps exist, okay to fail silently - } + const currentTestApps = await getCurrentTestApps(testAppDirectory); /** - * If we don't have enough test apps, we make enough. - * You can also force this setup if desired, e.g. you - * update the app-template. + * Setup test apps if needed */ - if (setup || currentTestApps.length < testAppsRequired) { - /** - * this will effectively clean the entire directory beforehand - * as opposed to cleaning the ones we aim to spawn. - */ - await Promise.all( - currentTestApps.map(async (appPath) => { - console.log(`Cleaning test app at path: ${chalk.bold(appPath)}`); - await cleanTestApp(appPath); - }) - ); - - currentTestApps = []; - - /** - * Generate the test apps and modify the configuration as needed - */ - await Promise.all( - testAppPaths.map(async (appPath) => { - console.log(`Generating test apps at path: ${chalk.bold(appPath)}`); - await generateTestApp({ - appPath, - database: { - client: 'sqlite', - connection: { - filename: './.tmp/data.db', - }, - useNullAsDefault: true, - }, - template: templateDir, - link: true, - }); - - /** - * Because we're running multiple test apps at the same time - * and the env file is generated by the generator with no way - * to override it, we manually remove the PORT key/value so when - * we set it further down for each playwright instance it works. - */ - const pathToEnv = path.join(appPath, '.env'); - const envFile = (await fs.readFile(pathToEnv)).toString(); - const envWithoutPort = envFile.replace('PORT=1337', ''); - await fs.writeFile(pathToEnv, envWithoutPort); - - currentTestApps.push(appPath); - }) - ); + const wasSetup = await setupTestApps({ + testAppDirectory, + testAppPaths, + templateDir, + setup, + currentTestApps, + setupTestEnvironment: null, // CLI doesn't need browser-specific setup + }); + if (wasSetup) { console.log( `${chalk.green('Successfully')} setup test apps for the following domains: ${chalk.bold( domains.join(', ') @@ -178,80 +107,18 @@ yargs } /** - * Run the tests in parallel based on concurrency value - * */ - const availableTestApps = [...currentTestApps]; - - const batches = []; - - for (let i = 0; i < domains.length; i += concurrency) { - batches.push(domains.slice(i, i + concurrency)); - } - - // eslint-disable-next-line no-plusplus - for (let i = 0; i < batches.length; i++) { - const batch = batches[i]; - let failingTests = 0; - await Promise.all( - batch.map(async (domain) => { - const config = domainConfigs[domain]; - - if (availableTestApps.length < config.testApps) { - console.error('Not enough test apps available; aborting'); - process.exit(1); - } - - // claim testApps for this domain to use - const testApps = availableTestApps.splice(-1 * config.testApps); - - /** - * We do not start up the apps; the test runner is responsible for that if it's necessary, - * but most CLI commands don't need a started instance of strapi - * Instead, we just pass in the path of the test apps assigned for this test runner via env - * */ - try { - const env = { - TEST_APPS: testApps.join(','), - JWT_SECRET: 'test-jwt-secret', - }; - - const domainDir = path.join(testsDir, domain); - const jestConfigPath = path.join(cwd, 'jest.config.cli.js'); - console.log('Running jest for domain', domain, 'in', domainDir); - // run the command 'jest --rootDir ' - await execa( - 'jest', - [ - '--config', - jestConfigPath, - '--rootDir', - domainDir, - '--color', - '--verbose', - '--runInBand', // tests must not run concurrently - ...argv._, - ], - { - stdio: 'inherit', - cwd: domainDir, // run from the domain directory - env, // pass it our custom env values - timeout: 2 * 60 * 1000, // 2 minutes - } - ); - } catch (err) { - // If any tests fail - console.error('Test suite failed for', domain); - failingTests += 1; - } - - // make them available again for the next batch - availableTestApps.push(...testApps); - }) - ); - if (failingTests > 0) { - throw new Error(`${failingTests} tests failed`); - } - } + * Run CLI tests + */ + await runCliTests({ + cwd, + testsDir, + testAppDirectory, + domains, + domainConfigs, + testAppPaths, + concurrency, + argv, + }); } catch (err) { console.error(chalk.red('Error running CLI tests:')); /** @@ -272,7 +139,8 @@ yargs description: 'clean the test app directory of all test apps', async handler() { try { - const currentTestApps = await fs.readdir(testAppDirectory); + const { cleanTestApp } = require('../helpers/test-app'); + const currentTestApps = await getCurrentTestApps(testAppDirectory); if (currentTestApps.length === 0) { console.log('No CLI test apps to clean'); @@ -280,8 +148,7 @@ yargs } await Promise.all( - currentTestApps.map(async (testAppName) => { - const appPath = path.join(testAppDirectory, testAppName); + currentTestApps.map(async (appPath) => { console.log(`Cleaning test app at path: ${chalk.bold(appPath)}`); await cleanTestApp(appPath); }) diff --git a/tests/scripts/run-e2e-tests.js b/tests/scripts/run-e2e-tests.js index 9da324b82b..d4dea20c0c 100644 --- a/tests/scripts/run-e2e-tests.js +++ b/tests/scripts/run-e2e-tests.js @@ -1,61 +1,29 @@ 'use strict'; const path = require('path'); -const execa = require('execa'); const fs = require('node:fs/promises'); const yargs = require('yargs'); const chalk = require('chalk'); const dotenv = require('dotenv'); -const { cleanTestApp, generateTestApp } = require('../helpers/test-app'); -const { createConfig } = require('../../playwright.base.config'); +const { setupTestEnvironment, runBrowserTests } = require('../utils/runners/browser-runner'); +const { publishYalc, setupTestApps, getCurrentTestApps } = require('../utils/runners/shared-setup'); const cwd = path.resolve(__dirname, '../..'); const testAppDirectory = path.join(cwd, 'test-apps', 'e2e'); -const testRoot = path.join(cwd, 'tests', 'e2e', 'browser'); +const testRoot = path.join(cwd, 'tests', 'e2e'); const testDomainRoot = path.join(testRoot, 'tests'); const templateDir = path.join(cwd, 'tests', 'e2e', 'app-template'); -const pathExists = async (path) => { +const pathExists = async (filePath) => { try { - await fs.access(path); + await fs.access(filePath); return true; } catch (err) { return false; } }; -/** - * Updates the env file for a generated test app - * - Removes the PORT key/value from generated app .env - * - Uses e2e/app-template/config/features.js to enable future features in the generated app - */ -const setupTestEnvironment = async (generatedAppPath) => { - /** - * Because we're running multiple test apps at the same time - * and the env file is generated by the generator with no way - * to override it, we manually remove the PORT key/value so when - * we set it further down for each playwright instance it works. - */ - const pathToEnv = path.join(generatedAppPath, '.env'); - const envFile = (await fs.readFile(pathToEnv)).toString(); - const envWithoutPort = envFile.replace('PORT=1337', ''); - await fs.writeFile(pathToEnv, envWithoutPort); - - /* - * Enable future features in the generated app manually since a template - * does not allow the config folder. - */ - const testRootFeaturesConfigPath = path.join(templateDir, 'config', 'features.js'); - const hasFeaturesConfig = await pathExists(testRootFeaturesConfigPath); - - if (!hasFeaturesConfig) return; - - const configFeatures = await fs.readFile(testRootFeaturesConfigPath); - const appFeaturesConfigPath = path.join(generatedAppPath, 'config', 'features.js'); - await fs.writeFile(appFeaturesConfigPath, configFeatures); -}; - yargs .parserConfiguration({ /** @@ -105,9 +73,7 @@ yargs /** * Publishing all packages to the yalc store */ - await execa('node', [path.join(__dirname, '../..', 'scripts', 'yalc-publish.js')], { - stdio: 'inherit', - }); + await publishYalc(cwd); /** * We don't need to spawn more apps than we have domains, @@ -124,52 +90,21 @@ yargs path.join(testAppDirectory, `test-app-${i}`) ); - let currentTestApps = []; - - try { - currentTestApps = await fs.readdir(testAppDirectory); - } catch (err) { - // no test apps exist, okay to fail silently - } + const currentTestApps = await getCurrentTestApps(testAppDirectory); /** - * If we don't have enough test apps, we make enough. - * You can also force this setup if desired, e.g. you - * update the app-template. + * Setup test apps if needed */ - if (setup || currentTestApps.length < testAppsToSpawn) { - /** - * this will effectively clean the entire directory before hand - * as opposed to cleaning the ones we aim to spawn. - */ - await Promise.all( - currentTestApps.map(async (testAppName) => { - const appPath = path.join(testAppDirectory, testAppName); - console.log(`cleaning test app at path: ${chalk.bold(appPath)}`); - await cleanTestApp(appPath); - }) - ); - - await Promise.all( - testAppPaths.map(async (appPath) => { - console.log(`generating test apps at path: ${chalk.bold(appPath)}`); - await generateTestApp({ - appPath, - database: { - client: 'sqlite', - connection: { - filename: './.tmp/data.db', - }, - useNullAsDefault: true, - }, - template: templateDir, - link: true, - }); - - await setupTestEnvironment(appPath); - }) - ); + const wasSetup = await setupTestApps({ + testAppDirectory, + testAppPaths, + templateDir, + setup, + currentTestApps: currentTestApps.map((appPath) => path.basename(appPath)), + setupTestEnvironment, + }); + if (wasSetup) { console.log( `${chalk.green('Successfully')} setup test apps for the following domains: ${chalk.bold( domains.join(', ') @@ -182,187 +117,16 @@ yargs } /** - * You can't change the webserver configuration of playwright directly so they'd - * all be looking at the same test app which we don't want, instead we'll generate - * a playwright config based off the base one + * Run browser tests */ - const chunkedDomains = domains.reduce((acc, _, i) => { - if (i % testAppsToSpawn === 0) acc.push(domains.slice(i, i + testAppsToSpawn)); - return acc; - }, []); - - // eslint-disable-next-line no-plusplus - for (let i = 0; i < chunkedDomains.length; i++) { - const domains = chunkedDomains[i]; - - await Promise.all( - domains.map(async (domain, j) => { - const testAppPath = testAppPaths[j]; - const port = 8000 + j; - - const pathToPlaywrightConfig = path.join(testAppPath, 'playwright.config.js'); - - console.log( - `Creating playwright config for domain: ${chalk.blue( - domain - )}, at path: ${chalk.yellow(testAppPath)}` - ); - - const config = createConfig({ - testDir: path.join(testDomainRoot, domain), - port, - appDir: testAppPath, - reportFileName: `playwright-${domain}-${port}.xml`, - }); - - const configFileTemplate = ` -const config = ${JSON.stringify(config)} - -module.exports = config - `; - - await fs.writeFile(pathToPlaywrightConfig, configFileTemplate); - - // Store the filesystem state with git so it can be reset between tests - // TODO: if we have a large test test suite, it might be worth it to run a `strapi start` and then shutdown here to generate documentation and types only once and save unneccessary server restarts from those files being cleared every time - console.log('Initializing git'); - - const gitUser = ['-c', 'user.name=Strapi CLI', '-c', 'user.email=test@strapi.io']; - - await execa('git', [...gitUser, 'init'], { - stdio: 'inherit', - cwd: testAppPath, - }); - - // we need to use -A to track even hidden files like .env; remember we're only using git as a file state manager - await execa('git', [...gitUser, 'add', '-A', '.'], { - stdio: 'inherit', - cwd: testAppPath, - }); - - await execa('git', [...gitUser, 'commit', '-m', 'initial commit'], { - stdio: 'inherit', - cwd: testAppPath, - }); - - // We need to generate the typescript and documentation files to avoid re-generating after each file reset - - // Start Strapi and wait for it to be ready - console.log(`Starting Strapi for domain '${domain}' to generate files...`); - const strapiProcess = execa('npm', ['run', 'develop'], { - cwd: testAppPath, - env: { - PORT: port, - STRAPI_DISABLE_EE: !process.env.STRAPI_LICENSE, - }, - detached: true, // This is important for CI - }); - - // Wait for Strapi to be ready by checking HTTP endpoint - await new Promise((resolve, reject) => { - const startTime = Date.now(); - const timeout = 160 * 1000; // 160 seconds, matching Playwright's timeout - const checkInterval = 1000; // Check every second - - const checkServer = async () => { - try { - const response = await fetch(`http://127.0.0.1:${port}/_health`); - if (response.ok) { - console.log('Strapi is ready, shutting down...'); - // In CI, we need to kill the entire process group - if (process.env.CI) { - process.kill(-strapiProcess.pid, 'SIGINT'); - } else { - strapiProcess.kill('SIGINT'); - } - resolve(); - return; - } - } catch (err) { - // Server not ready yet, continue checking - } - - if (Date.now() - startTime > timeout) { - console.log('Timeout reached, forcing shutdown...'); - if (process.env.CI) { - process.kill(-strapiProcess.pid, 'SIGKILL'); - } else { - strapiProcess.kill('SIGKILL'); - } - reject(new Error('Strapi failed to start within timeout period')); - return; - } - - setTimeout(checkServer, checkInterval); - }; - - // Start checking - checkServer(); - - // Log stdout and stderr for debugging - strapiProcess.stdout.on('data', (data) => { - console.log(`[stdout] ${data.toString().trim()}`); - }); - - strapiProcess.stderr.on('data', (data) => { - console.error(`[stderr] ${data.toString().trim()}`); - }); - - strapiProcess.on('error', (err) => { - console.error(`[Strapi ERROR] Process error:`, err); - reject(err); - }); - - strapiProcess.on('exit', (code) => { - console.log(`Strapi process exited with code ${code}`); - }); - }); - - // Double check that Strapi has shut down - await new Promise((resolve) => { - const checkPort = async () => { - try { - await fetch(`http://127.0.0.1:${port}/_health`); - // If we can connect, port is still in use - setTimeout(checkPort, 1000); - } catch (err) { - // Port is free - resolve(); - } - }; - checkPort(); - }); - - // Commit the generated files - await execa('git', [...gitUser, 'add', '-A', '.'], { - stdio: 'inherit', - cwd: testAppPath, - }); - - await execa('git', [...gitUser, 'commit', '-m', 'commit generated files'], { - stdio: 'inherit', - cwd: testAppPath, - }); - - console.log(`Running ${chalk.blue(domain)} e2e tests`); - - await execa( - 'yarn', - ['playwright', 'test', '--config', pathToPlaywrightConfig, ...argv._], - { - stdio: 'inherit', - cwd, - env: { - PORT: port, - HOST: '127.0.0.1', - TEST_APP_PATH: testAppPath, - STRAPI_DISABLE_EE: !process.env.STRAPI_LICENSE, - }, - } - ); - }) - ); - } + await runBrowserTests({ + cwd, + testAppPaths, + testDomainRoot, + domains, + testAppsToSpawn, + argv, + }); } catch (err) { console.error(chalk.red('Error running e2e tests:')); /** @@ -383,7 +147,8 @@ module.exports = config description: 'clean the test app directory of all test apps', async handler() { try { - const currentTestApps = await fs.readdir(testAppDirectory); + const { cleanTestApp } = require('../helpers/test-app'); + const currentTestApps = await getCurrentTestApps(testAppDirectory); if (currentTestApps.length === 0) { console.log('No e2e test apps to clean'); @@ -391,9 +156,8 @@ module.exports = config } await Promise.all( - currentTestApps.map(async (testAppName) => { - const appPath = path.join(testAppDirectory, testAppName); - console.log(`cleaning test app at path: ${chalk.bold(appPath)}`); + currentTestApps.map(async (appPath) => { + console.log(`Cleaning test app at path: ${chalk.bold(appPath)}`); await cleanTestApp(appPath); }) ); diff --git a/tests/e2e/browser/utils/content-creation.ts b/tests/utils/content-creation.ts similarity index 100% rename from tests/e2e/browser/utils/content-creation.ts rename to tests/utils/content-creation.ts diff --git a/tests/e2e/browser/utils/content-types.ts b/tests/utils/content-types.ts similarity index 100% rename from tests/e2e/browser/utils/content-types.ts rename to tests/utils/content-types.ts diff --git a/tests/e2e/browser/utils/dts-export.ts b/tests/utils/dts-export.ts similarity index 70% rename from tests/e2e/browser/utils/dts-export.ts rename to tests/utils/dts-export.ts index 74822151c0..4a033d2eab 100644 --- a/tests/e2e/browser/utils/dts-export.ts +++ b/tests/utils/dts-export.ts @@ -2,7 +2,7 @@ import type { Core } from '@strapi/strapi'; import dts from '@strapi/data-transfer'; import { createStrapi } from '@strapi/strapi'; -import { ALLOWED_CONTENT_TYPES } from '../constants'; +import { ALLOWED_CONTENT_TYPES } from '../e2e/constants'; const { file: { @@ -57,8 +57,23 @@ export const exportData = async (): Promise => { try { const results = await engine.transfer(); + const { destination: dest, engine: engineResults } = results; - console.log(JSON.stringify(results.engine, null, 2)); + // Enhanced output with details (from CLI version) + if (dest?.file?.path) { + const path = require('path'); + const relativeArchivePath = path.relative(process.cwd(), dest.file.path); + console.log(`Dataset exported to: ${relativeArchivePath}`); + console.log('The export contains:'); + console.log(` - ${engineResults.schemas?.count ?? 0} schemas`); + console.log(` - ${engineResults.entities?.count ?? 0} entities`); + console.log(` - ${engineResults.links?.count ?? 0} links`); + console.log(` - ${engineResults.assets?.count ?? 0} assets`); + console.log(` - ${engineResults.configuration?.count ?? 0} configs`); + } else { + // Fallback to JSON output (browser version) + console.log(JSON.stringify(results.engine, null, 2)); + } } catch { console.error('Export process failed.'); process.exit(1); diff --git a/tests/e2e/browser/utils/dts-import.ts b/tests/utils/dts-import.ts similarity index 91% rename from tests/e2e/browser/utils/dts-import.ts rename to tests/utils/dts-import.ts index b9aee0c00c..e5a945d3c7 100644 --- a/tests/e2e/browser/utils/dts-import.ts +++ b/tests/utils/dts-import.ts @@ -1,5 +1,5 @@ -import { resolve, join } from 'path'; -import { ALLOWED_CONTENT_TYPES, CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } from '../constants'; +import { resolve } from 'path'; +import { ALLOWED_CONTENT_TYPES, CUSTOM_TRANSFER_TOKEN_ACCESS_KEY } from '../e2e/constants'; const { file: { @@ -25,7 +25,9 @@ export const resetDatabaseAndImportDataFromPath = async ( modifiedContentTypesFn: (cts: string[]) => string[] = (cts) => cts, configuration: RestoreConfiguration = { coreStore: true } ) => { - const filePath = resolve(__dirname, '../data/', file); + // If file is already an absolute path, use it; otherwise resolve relative to e2e/data + const filePath = + file.startsWith('/') || file.includes('\\') ? file : resolve(__dirname, '../e2e/data/', file); const source = createSourceProvider(filePath); const includedTypes = modifiedContentTypesFn(ALLOWED_CONTENT_TYPES); const destination = createDestinationProvider(includedTypes, configuration); diff --git a/tests/e2e/browser/utils/file-reset.ts b/tests/utils/file-reset.ts similarity index 100% rename from tests/e2e/browser/utils/file-reset.ts rename to tests/utils/file-reset.ts diff --git a/tests/e2e/cli/utils/fs.js b/tests/utils/fs.js similarity index 100% rename from tests/e2e/cli/utils/fs.js rename to tests/utils/fs.js diff --git a/tests/e2e/browser/utils/global-setup.ts b/tests/utils/global-setup.ts similarity index 100% rename from tests/e2e/browser/utils/global-setup.ts rename to tests/utils/global-setup.ts diff --git a/tests/e2e/cli/utils/helpers.js b/tests/utils/helpers.js similarity index 100% rename from tests/e2e/cli/utils/helpers.js rename to tests/utils/helpers.js diff --git a/tests/e2e/browser/utils/login.ts b/tests/utils/login.ts similarity index 92% rename from tests/e2e/browser/utils/login.ts rename to tests/utils/login.ts index 13d2ff04d2..bb1d14ae54 100644 --- a/tests/e2e/browser/utils/login.ts +++ b/tests/utils/login.ts @@ -1,5 +1,5 @@ import type { Page } from '@playwright/test'; -import { ADMIN_EMAIL_ADDRESS, ADMIN_PASSWORD } from '../constants'; +import { ADMIN_EMAIL_ADDRESS, ADMIN_PASSWORD } from '../e2e/constants'; /** * Log in to an e2e test app diff --git a/tests/e2e/browser/utils/rate-limit.ts b/tests/utils/rate-limit.ts similarity index 100% rename from tests/e2e/browser/utils/rate-limit.ts rename to tests/utils/rate-limit.ts diff --git a/tests/e2e/browser/utils/restart.ts b/tests/utils/restart.ts similarity index 100% rename from tests/e2e/browser/utils/restart.ts rename to tests/utils/restart.ts diff --git a/tests/utils/runners/browser-runner.js b/tests/utils/runners/browser-runner.js new file mode 100644 index 0000000000..01e8b35c78 --- /dev/null +++ b/tests/utils/runners/browser-runner.js @@ -0,0 +1,238 @@ +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const fs = require('node:fs/promises'); +const { createConfig } = require('../../../playwright.base.config'); + +const pathExists = async (filePath) => { + try { + await fs.access(filePath); + return true; + } catch (err) { + return false; + } +}; + +/** + * Updates the env file for a generated test app + * - Removes the PORT key/value from generated app .env + * - Uses e2e/app-template/config/features.js to enable future features in the generated app + */ +const setupTestEnvironment = async (generatedAppPath, templateDir) => { + /** + * Because we're running multiple test apps at the same time + * and the env file is generated by the generator with no way + * to override it, we manually remove the PORT key/value so when + * we set it further down for each playwright instance it works. + */ + const pathToEnv = path.join(generatedAppPath, '.env'); + const envFile = (await fs.readFile(pathToEnv)).toString(); + const envWithoutPort = envFile.replace('PORT=1337', ''); + await fs.writeFile(pathToEnv, envWithoutPort); + + /* + * Enable future features in the generated app manually since a template + * does not allow the config folder. + */ + const testRootFeaturesConfigPath = path.join(templateDir, 'config', 'features.js'); + const hasFeaturesConfig = await pathExists(testRootFeaturesConfigPath); + + if (!hasFeaturesConfig) return; + + const configFeatures = await fs.readFile(testRootFeaturesConfigPath); + const appFeaturesConfigPath = path.join(generatedAppPath, 'config', 'features.js'); + await fs.writeFile(appFeaturesConfigPath, configFeatures); +}; + +/** + * Run browser (Playwright) tests + */ +const runBrowserTests = async ({ + cwd, + testAppPaths, + testDomainRoot, + domains, + testAppsToSpawn, + argv, +}) => { + /** + * You can't change the webserver configuration of playwright directly so they'd + * all be looking at the same test app which we don't want, instead we'll generate + * a playwright config based off the base one + */ + const chunkedDomains = domains.reduce((acc, _, i) => { + if (i % testAppsToSpawn === 0) acc.push(domains.slice(i, i + testAppsToSpawn)); + return acc; + }, []); + + // eslint-disable-next-line no-plusplus + for (let i = 0; i < chunkedDomains.length; i++) { + const domainBatch = chunkedDomains[i]; + + await Promise.all( + domainBatch.map(async (domain, j) => { + const testAppPath = testAppPaths[j]; + const port = 8000 + j; + + const pathToPlaywrightConfig = path.join(testAppPath, 'playwright.config.js'); + + console.log(`Creating playwright config for domain: ${domain}, at path: ${testAppPath}`); + + const config = createConfig({ + testDir: path.join(testDomainRoot, domain), + port, + appDir: testAppPath, + reportFileName: `playwright-${domain}-${port}.xml`, + }); + + const configFileTemplate = ` +const config = ${JSON.stringify(config)} + +module.exports = config + `; + + await fs.writeFile(pathToPlaywrightConfig, configFileTemplate); + + // Store the filesystem state with git so it can be reset between tests + // TODO: if we have a large test test suite, it might be worth it to run a `strapi start` and then shutdown here to generate documentation and types only once and save unneccessary server restarts from those files being cleared every time + console.log('Initializing git'); + + const gitUser = ['-c', 'user.name=Strapi CLI', '-c', 'user.email=test@strapi.io']; + + await execa('git', [...gitUser, 'init'], { + stdio: 'inherit', + cwd: testAppPath, + }); + + // we need to use -A to track even hidden files like .env; remember we're only using git as a file state manager + await execa('git', [...gitUser, 'add', '-A', '.'], { + stdio: 'inherit', + cwd: testAppPath, + }); + + await execa('git', [...gitUser, 'commit', '-m', 'initial commit'], { + stdio: 'inherit', + cwd: testAppPath, + }); + + // We need to generate the typescript and documentation files to avoid re-generating after each file reset + + // Start Strapi and wait for it to be ready + console.log(`Starting Strapi for domain '${domain}' to generate files...`); + const strapiProcess = execa('npm', ['run', 'develop'], { + cwd: testAppPath, + env: { + PORT: port, + STRAPI_DISABLE_EE: !process.env.STRAPI_LICENSE, + }, + detached: true, // This is important for CI + }); + + // Wait for Strapi to be ready by checking HTTP endpoint + await new Promise((resolve, reject) => { + const startTime = Date.now(); + const timeout = 160 * 1000; // 160 seconds, matching Playwright's timeout + const checkInterval = 1000; // Check every second + + const checkServer = async () => { + try { + const response = await fetch(`http://127.0.0.1:${port}/_health`); + if (response.ok) { + console.log('Strapi is ready, shutting down...'); + // In CI, we need to kill the entire process group + if (process.env.CI) { + process.kill(-strapiProcess.pid, 'SIGINT'); + } else { + strapiProcess.kill('SIGINT'); + } + resolve(); + return; + } + } catch (err) { + // Server not ready yet, continue checking + } + + if (Date.now() - startTime > timeout) { + console.log('Timeout reached, forcing shutdown...'); + if (process.env.CI) { + process.kill(-strapiProcess.pid, 'SIGKILL'); + } else { + strapiProcess.kill('SIGKILL'); + } + reject(new Error('Strapi failed to start within timeout period')); + return; + } + + setTimeout(checkServer, checkInterval); + }; + + // Start checking + checkServer(); + + // Log stdout and stderr for debugging + strapiProcess.stdout.on('data', (data) => { + console.log(`[stdout] ${data.toString().trim()}`); + }); + + strapiProcess.stderr.on('data', (data) => { + console.error(`[stderr] ${data.toString().trim()}`); + }); + + strapiProcess.on('error', (err) => { + console.error(`[Strapi ERROR] Process error:`, err); + reject(err); + }); + + strapiProcess.on('exit', (code) => { + console.log(`Strapi process exited with code ${code}`); + }); + }); + + // Double check that Strapi has shut down + await new Promise((resolve) => { + const checkPort = async () => { + try { + await fetch(`http://127.0.0.1:${port}/_health`); + // If we can connect, port is still in use + setTimeout(checkPort, 1000); + } catch (err) { + // Port is free + resolve(); + } + }; + checkPort(); + }); + + // Commit the generated files + await execa('git', [...gitUser, 'add', '-A', '.'], { + stdio: 'inherit', + cwd: testAppPath, + }); + + await execa('git', [...gitUser, 'commit', '-m', 'commit generated files'], { + stdio: 'inherit', + cwd: testAppPath, + }); + + console.log(`Running ${domain} e2e tests`); + + await execa('yarn', ['playwright', 'test', '--config', pathToPlaywrightConfig, ...argv._], { + stdio: 'inherit', + cwd, + env: { + PORT: port, + HOST: '127.0.0.1', + TEST_APP_PATH: testAppPath, + STRAPI_DISABLE_EE: !process.env.STRAPI_LICENSE, + }, + }); + }) + ); + } +}; + +module.exports = { + setupTestEnvironment, + runBrowserTests, +}; diff --git a/tests/utils/runners/cli-runner.js b/tests/utils/runners/cli-runner.js new file mode 100644 index 0000000000..df3087eaad --- /dev/null +++ b/tests/utils/runners/cli-runner.js @@ -0,0 +1,143 @@ +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const fs = require('node:fs/promises'); + +/** + * Load domain-specific configuration + */ +const loadDomainConfigs = async (testsDir, domains, argv) => { + const loadDomainConfig = async (domain) => { + try { + const configPath = path.join(testsDir, domain, 'config.js'); + await fs.access(configPath); + // Import config.js and call it as a function + const config = require(configPath); + if (typeof config === 'function') { + return await config(argv); + } + return config; + } catch (e) { + // use default config + return { + testApps: 1, + }; + } + }; + + // Load the domain configs into an object with keys of the name of the test domain + const domainConfigs = {}; + await Promise.all( + domains.map(async (domain) => { + domainConfigs[domain] = await loadDomainConfig(domain); + }) + ); + + return domainConfigs; +}; + +/** + * Calculate the number of test apps required based on domain configs + */ +const calculateTestAppsRequired = (domainConfigs, concurrency) => { + // Determine the number of simultaneous test apps we need by taking the concurrency number of highest testApps requested from config + return Object.entries(domainConfigs) + .map(([, value]) => value.testApps) // Extract testApps values from config + .sort((a, b) => b - a) // Sort in descending order + .slice(0, concurrency) // Take the top X values + .reduce((acc, value) => acc + value, 0); // Sum up the values +}; + +/** + * Run CLI (Jest) tests + */ +const runCliTests = async ({ + cwd, + testsDir, + testAppDirectory, + domains, + domainConfigs, + testAppPaths, + concurrency, + argv, +}) => { + const availableTestApps = [...testAppPaths]; + + const batches = []; + + for (let i = 0; i < domains.length; i += concurrency) { + batches.push(domains.slice(i, i + concurrency)); + } + + // eslint-disable-next-line no-plusplus + for (let i = 0; i < batches.length; i++) { + const batch = batches[i]; + let failingTests = 0; + await Promise.all( + batch.map(async (domain) => { + const config = domainConfigs[domain]; + + if (availableTestApps.length < config.testApps) { + console.error('Not enough test apps available; aborting'); + process.exit(1); + } + + // claim testApps for this domain to use + const testApps = availableTestApps.splice(-1 * config.testApps); + + /** + * We do not start up the apps; the test runner is responsible for that if it's necessary, + * but most CLI commands don't need a started instance of strapi + * Instead, we just pass in the path of the test apps assigned for this test runner via env + * */ + try { + const env = { + TEST_APPS: testApps.join(','), + JWT_SECRET: 'test-jwt-secret', + }; + + const domainDir = path.join(testsDir, domain); + const jestConfigPath = path.join(cwd, 'jest.config.cli.js'); + console.log('Running jest for domain', domain, 'in', domainDir); + // run the command 'jest --rootDir ' + await execa( + 'jest', + [ + '--config', + jestConfigPath, + '--rootDir', + domainDir, + '--color', + '--verbose', + '--runInBand', // tests must not run concurrently + ...argv._, + ], + { + stdio: 'inherit', + cwd: domainDir, // run from the domain directory + env, // pass it our custom env values + timeout: 2 * 60 * 1000, // 2 minutes + } + ); + } catch (err) { + // If any tests fail + console.error('Test suite failed for', domain); + failingTests += 1; + } + + // make them available again for the next batch + availableTestApps.push(...testApps); + }) + ); + if (failingTests > 0) { + throw new Error(`${failingTests} tests failed`); + } + } +}; + +module.exports = { + loadDomainConfigs, + calculateTestAppsRequired, + runCliTests, +}; diff --git a/tests/utils/runners/shared-setup.js b/tests/utils/runners/shared-setup.js new file mode 100644 index 0000000000..4c32b4941c --- /dev/null +++ b/tests/utils/runners/shared-setup.js @@ -0,0 +1,102 @@ +'use strict'; + +const path = require('path'); +const execa = require('execa'); +const fs = require('node:fs/promises'); +const { cleanTestApp, generateTestApp } = require('../test-app'); + +/** + * Publish all packages to yalc store + */ +const publishYalc = async (cwd) => { + await execa('node', [path.join(cwd, 'scripts', 'yalc-publish.js')], { + stdio: 'inherit', + }); +}; + +/** + * Setup test apps - clean and generate + */ +const setupTestApps = async ({ + testAppDirectory, + testAppPaths, + templateDir, + setup, + currentTestApps, + setupTestEnvironment, +}) => { + /** + * If we don't have enough test apps, we make enough. + * You can also force this setup if desired, e.g. you + * update the app-template. + */ + if (setup || currentTestApps.length < testAppPaths.length) { + /** + * this will effectively clean the entire directory before hand + * as opposed to cleaning the ones we aim to spawn. + */ + await Promise.all( + currentTestApps.map(async (testAppName) => { + const appPath = + typeof testAppName === 'string' ? path.join(testAppDirectory, testAppName) : testAppName; + console.log(`Cleaning test app at path: ${appPath}`); + await cleanTestApp(appPath); + }) + ); + + /** + * Generate the test apps and modify the configuration as needed + */ + await Promise.all( + testAppPaths.map(async (appPath) => { + console.log(`Generating test apps at path: ${appPath}`); + await generateTestApp({ + appPath, + database: { + client: 'sqlite', + connection: { + filename: './.tmp/data.db', + }, + useNullAsDefault: true, + }, + template: templateDir, + link: true, + }); + + // Remove PORT from .env (common to both browser and CLI) + const pathToEnv = path.join(appPath, '.env'); + const envFile = (await fs.readFile(pathToEnv)).toString(); + const envWithoutPort = envFile.replace('PORT=1337', ''); + await fs.writeFile(pathToEnv, envWithoutPort); + + // Run additional setup if provided (browser-specific setupTestEnvironment) + if (setupTestEnvironment) { + await setupTestEnvironment(appPath, templateDir); + } + }) + ); + + return true; + } + + return false; +}; + +/** + * Get current test apps from directory + */ +const getCurrentTestApps = async (testAppDirectory) => { + try { + const apps = await fs.readdir(testAppDirectory); + return apps.map((appName) => path.join(testAppDirectory, appName)); + } catch (err) { + // no test apps exist, okay to fail silently + return []; + } +}; + +module.exports = { + publishYalc, + setupTestApps, + getCurrentTestApps, +}; diff --git a/tests/e2e/browser/scripts/dts-export.ts b/tests/utils/scripts/dts-export.ts similarity index 100% rename from tests/e2e/browser/scripts/dts-export.ts rename to tests/utils/scripts/dts-export.ts diff --git a/tests/e2e/browser/scripts/dts-import.ts b/tests/utils/scripts/dts-import.ts similarity index 59% rename from tests/e2e/browser/scripts/dts-import.ts rename to tests/utils/scripts/dts-import.ts index 30055a50de..501d76a1d1 100644 --- a/tests/e2e/browser/scripts/dts-import.ts +++ b/tests/utils/scripts/dts-import.ts @@ -1,13 +1,11 @@ -import { resetDatabaseAndImportDataFromPath } from '../utils/dts-import'; +import { resetDatabaseAndImportDataFromPath } from '../dts-import'; const importData = async () => { const args = process.argv.slice(2); const filePath = args[0]; if (!filePath) { - console.error( - 'Please provide the name of the file you want to import from tests/e2e/browser/data' - ); + console.error('Please provide the name of the file you want to import from tests/e2e/data'); process.exit(1); } diff --git a/tests/e2e/browser/scripts/endpoints.ts b/tests/utils/scripts/endpoints.ts similarity index 100% rename from tests/e2e/browser/scripts/endpoints.ts rename to tests/utils/scripts/endpoints.ts diff --git a/tests/e2e/browser/utils/setup.ts b/tests/utils/setup.ts similarity index 100% rename from tests/e2e/browser/utils/setup.ts rename to tests/utils/setup.ts diff --git a/tests/e2e/browser/utils/shared.ts b/tests/utils/shared.ts similarity index 100% rename from tests/e2e/browser/utils/shared.ts rename to tests/utils/shared.ts diff --git a/tests/e2e/browser/utils/signup.ts b/tests/utils/signup.ts similarity index 96% rename from tests/e2e/browser/utils/signup.ts rename to tests/utils/signup.ts index 32691faf91..64226d78ec 100644 --- a/tests/e2e/browser/utils/signup.ts +++ b/tests/utils/signup.ts @@ -1,5 +1,5 @@ import type { Page } from '@playwright/test'; -import { ADMIN_EMAIL_ADDRESS, ADMIN_PASSWORD, TITLE_HOME } from '../constants'; +import { ADMIN_EMAIL_ADDRESS, ADMIN_PASSWORD, TITLE_HOME } from '../e2e/constants'; /** * Fill in the sign-up form with valid values diff --git a/tests/e2e/cli/utils/test-app.js b/tests/utils/test-app.js similarity index 100% rename from tests/e2e/cli/utils/test-app.js rename to tests/utils/test-app.js