strapi/tests/scripts/run-cli-tests.js
Marc Roig 43f30b747f
chore: merge develop into v5 main (#21108)
* cron type fix

* Fix typo of query key from 'providers' to 'get-providers'

* Closing #19644 fix filters type

* node-scadule updated + types updated

* Fix formating errors

* fix formatting

* update lock file

* fix patreon oauth 400 error

from lack of user-agent header

* test: backport cli tests (#20433)

* fix(chore): increase specificity of the Lightning icon color (#20467)

* test: temporarily disable broken edit ctb tests on CI (#20481)

* feat(cli): cloud cli commands (v4) (#20119)

* feat(cli): add cloud commands

Co-authored-by: Gonzalo Garcia <nouvellegon@gmail.com>
Co-authored-by: nathan-pichon <nathan.pichon@strapi.io>
Co-authored-by: Abdallah M <55534657+abdallahmz@users.noreply.github.com>

* v4.25.0 (#20500)

* NPS: Update frequency of the NPS (#20492)

* enhancement(admin): change postFirstDismissal and display delays

* enhancement(admin): change the display delay

* fix: prevent use of local ips on webhooks (#20487)

* chore: mask error on webhook manual trigger

* feat: prevent using local ips

* feat: display webhook edit error

* chore: pr suggestion

* chore: api tests

* chore: allow local ips on development

* chore: only run check on production

* feat: include internationalized urls

* fix: prettier

* Add: Strapi deploy command to README files

* v4.25.1

* Update @aws-sdk/client-s3 package

* feat(cli): add browser logout step (#20502)

* feat(cli): add browser log out step

* handle error whiile fetching the config

* Update LICENSE packing for packages for v4 (#20576)

* feat(create-strapi-app): remove the cloud project creation part (#20561)

* feat(create-strapi-app): remove the cloud project creation part

* fix(create-strapi-app): adding new parameter to cloud service instantiation

* Update Yarn to 4.3.1

Signed-off-by: Sora Morimoto <sora@morimoto.io>

* feat(cli): trigger login sequence when token is missing or invalid  (#20572)

* feat(cli): launch login when auth fails

* fix(cli): abstract create project fn

* fix(cli): guidelines

* fix(cli): rebase

---------

Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>

* fix clone entity, #20509 (#20531)

* chore: bump glob from 7.2.0 to 9.0.0

* chore: bump glob to v10.4.2 in core/strapi

* update yarn.lock

* removed redundant packages/core/strapi/src/load/glob.ts file

* v4.25.2 to main (#20676)

* Fix typo of query key from 'providers' to 'get-providers'

* Closing #19644 fix filters type

* fix patreon oauth 400 error

from lack of user-agent header

* Add: Strapi deploy command to README files

* Update @aws-sdk/client-s3 package

* feat(cli): add browser logout step (#20502)

* feat(cli): add browser log out step

* handle error whiile fetching the config

* Update LICENSE packing for packages for v4 (#20576)

* feat(create-strapi-app): remove the cloud project creation part (#20561)

* feat(create-strapi-app): remove the cloud project creation part

* fix(create-strapi-app): adding new parameter to cloud service instantiation

* Update Yarn to 4.3.1

Signed-off-by: Sora Morimoto <sora@morimoto.io>

* feat(cli): trigger login sequence when token is missing or invalid  (#20572)

* feat(cli): launch login when auth fails

* fix(cli): abstract create project fn

* fix(cli): guidelines

* fix(cli): rebase

---------

Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>

* fix: support string array

* fix clone entity, #20509 (#20531)

* v4.25.2

---------

Signed-off-by: Sora Morimoto <sora@morimoto.io>
Co-authored-by: smoothdvd <madfxgao@gmail.com>
Co-authored-by: Micah Riggan <micahriggan@gmail.com>
Co-authored-by: Tewson Seeoun <tewson.seeoun@gmail.com>
Co-authored-by: Maxime Castres <mcastres@student.42.fr>
Co-authored-by: Alex Supkay <asupkay1124@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>
Co-authored-by: Abdallah M <55534657+abdallahmz@users.noreply.github.com>
Co-authored-by: Jean-Sébastien Herbaux <jean-sebastien.herbaux@epitech.eu>
Co-authored-by: Nathan Pichon <nathan.pichon@strapi.io>
Co-authored-by: Sora Morimoto <sora@morimoto.io>
Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Kirill Verevkin <kira795@yandex.ru>

* v4.25.2 (#20675)

* fix: support string array

* v4.25.2

---------

Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>

* feat(cli): use project name from package json by default (#20479)

* chore: change cloud message in homepage (#20685)

* chore(cloud-cli): migrate to fs-extra (#20695)

* feat(cloud-cli): migrate compress-files.ts to fs-extra

* feat(cloud-cli): migrate pkg.ts to fs-extra

* fix(cloud-cli): update using promises in recursive function

* feat(cli): Add projects list command (#20694)

* feat(cli): projects list command

* fix: updating contributing guide workflow

* chore: release v4.25.3 (#20722)

* fix: invalid path separator (#20740)

* fix: invalid path separator

* fix: prettier

* v4.25.4 to develop (#20832)

* 4.25.4 to main (#20833)

* cron type fix

* node-scadule updated + types updated

* Fix formating errors

* fix formatting

* update lock file

* chore(cloud-cli): migrate to fs-extra (#20695)

* feat(cloud-cli): migrate compress-files.ts to fs-extra

* feat(cloud-cli): migrate pkg.ts to fs-extra

* fix(cloud-cli): update using promises in recursive function

* feat(cli): Add projects list command (#20694)

* feat(cli): projects list command

* fix: invalid path separator (#20740)

* fix: invalid path separator

* fix: prettier

* v4.25.4

---------

Co-authored-by: Boegie19 <34578426+Boegie19@users.noreply.github.com>
Co-authored-by: Nathan Pichon <nathan.pichon@strapi.io>
Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>
Co-authored-by: Rémi de Juvigny <8087692+remidej@users.noreply.github.com>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>

* Chore: Removing some people from the issue auto-assignment

Removing Simen and Nick from the array of people issues will be auto-assigned to

* fix(cloud-cli): avoid blocking event loop in deploy command (#20850)

* chore(cloud-cli): update error handling for config and logs at the ends of function execution

* fix(cloud-cli): clear timeout before returning - free the event loop from waiting

* feat(cli): add project link command to cloud cli (#20714)

* feat(cli): add link command

* 4.25.5 to main (#20873)

* cron type fix

* node-scadule updated + types updated

* Fix formating errors

* fix formatting

* update lock file

* chore(cloud-cli): migrate to fs-extra (#20695)

* feat(cloud-cli): migrate compress-files.ts to fs-extra

* feat(cloud-cli): migrate pkg.ts to fs-extra

* fix(cloud-cli): update using promises in recursive function

* feat(cli): Add projects list command (#20694)

* feat(cli): projects list command

* fix: updating contributing guide workflow

* fix: invalid path separator (#20740)

* fix: invalid path separator

* fix: prettier

* v4.25.4 to develop (#20832)

* Chore: Removing some people from the issue auto-assignment

Removing Simen and Nick from the array of people issues will be auto-assigned to

* fix(cloud-cli): avoid blocking event loop in deploy command (#20850)

* chore(cloud-cli): update error handling for config and logs at the ends of function execution

* fix(cloud-cli): clear timeout before returning - free the event loop from waiting

* feat(cli): add project link command to cloud cli (#20714)

* feat(cli): add link command

* v4.25.5

---------

Co-authored-by: Boegie19 <34578426+Boegie19@users.noreply.github.com>
Co-authored-by: Nathan Pichon <nathan.pichon@strapi.io>
Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>
Co-authored-by: José Luis <alagunasalahaddin@live.com>
Co-authored-by: Rémi de Juvigny <8087692+remidej@users.noreply.github.com>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>
Co-authored-by: DMehaffy <derrickmehaffy@gmail.com>

* v4.25.5 to develop (#20872)

* 4.25.4 to main (#20833)

* cron type fix

* node-scadule updated + types updated

* Fix formating errors

* fix formatting

* update lock file

* chore(cloud-cli): migrate to fs-extra (#20695)

* feat(cloud-cli): migrate compress-files.ts to fs-extra

* feat(cloud-cli): migrate pkg.ts to fs-extra

* fix(cloud-cli): update using promises in recursive function

* feat(cli): Add projects list command (#20694)

* feat(cli): projects list command

* fix: invalid path separator (#20740)

* fix: invalid path separator

* fix: prettier

* v4.25.4

---------

Co-authored-by: Boegie19 <34578426+Boegie19@users.noreply.github.com>
Co-authored-by: Nathan Pichon <nathan.pichon@strapi.io>
Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>
Co-authored-by: Rémi de Juvigny <8087692+remidej@users.noreply.github.com>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>

* v4.25.5

---------

Co-authored-by: Rémi de Juvigny <8087692+remidej@users.noreply.github.com>
Co-authored-by: Boegie19 <34578426+Boegie19@users.noreply.github.com>
Co-authored-by: Nathan Pichon <nathan.pichon@strapi.io>
Co-authored-by: Gonzalo Andres Garcia <nouvellegon@gmail.com>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>

* fix custom email provider test issue #19122 (#19123)

* fix custom email provider test issue #19122

* chore(email): prettier clean up

---------

Co-authored-by: Jamie Howard <jamie.howard@strapi.io>

* Changed Discord username to fit change Discord made.

* v4.25.6

* fix(cli): Update 'project not found' error message in deploy command (#20923)

* chore: aggregate test result to add a single required status check and make it dynamic

* shard ee tests+ fix broken platform (#20914)

* v4.25.7

* RBAC Action Aliases - v4 (#20954)

* test(cli): add list command tests (#20949)

* feat(cloud-cli): preselect node-version based on local node-version (#20959)

* [Fix] Validate cloning as entity creation so field validations aren't skipped e.g. unique constraints (#20963)

* flatten CI workflow tests (#20969)

* v4.25.8 release to develop (#21011)

* Removing workflows the support team doesn't need anymore

* chore: getstarted schema sync between v4-v5 (#21047)

* Chore(CLI): Add validation to prevent deployment of suspended projects (#20976)

* chore(cli): check project suspension

* Prettier fix

* chore(deps): update axios to 1.7.4 (#21014)

* fix(cli): Update endpoint path for listLinkProjects (#21052)

* chore: update lint-staged to 15.2.9 (#21075)

* v4.25.9

* fix: issue 21079

* fix: rich text selection & deletion issues

* fix: build

* fix: type

* fix: skip failing cli tests

* chore: fix jest options in ci

---------

Signed-off-by: Sora Morimoto <sora@morimoto.io>
Co-authored-by: Boegie19 <34578426+Boegie19@users.noreply.github.com>
Co-authored-by: smoothdvd <madfxgao@gmail.com>
Co-authored-by: Micah Riggan <micahriggan@gmail.com>
Co-authored-by: Tewson Seeoun <tewson.seeoun@gmail.com>
Co-authored-by: Ben Irvin <ben.irvin@strapi.io>
Co-authored-by: Simone <startae14@gmail.com>
Co-authored-by: Nathan Pichon <nathan.pichon@strapi.io>
Co-authored-by: Gonzalo Garcia <nouvellegon@gmail.com>
Co-authored-by: Abdallah M <55534657+abdallahmz@users.noreply.github.com>
Co-authored-by: Maxime Castres <mcastres@student.42.fr>
Co-authored-by: Convly <jean-sebastien.herbaux@epitech.eu>
Co-authored-by: Alex Supkay <asupkay1124@gmail.com>
Co-authored-by: Alexandre BODIN <alexandrebodin@users.noreply.github.com>
Co-authored-by: Sora Morimoto <sora@morimoto.io>
Co-authored-by: Alexandre Bodin <bodin.alex@gmail.com>
Co-authored-by: Kirill Verevkin <kira795@yandex.ru>
Co-authored-by: chrismuiruriz <chrismuiruri007@gmail.com>
Co-authored-by: José Luis <alagunasalahaddin@live.com>
Co-authored-by: Rémi de Juvigny <8087692+remidej@users.noreply.github.com>
Co-authored-by: Rémi de Juvigny <remi.dejuvigny@strapi.io>
Co-authored-by: DMehaffy <derrickmehaffy@gmail.com>
Co-authored-by: ahallaha <104538552+ahallaha@users.noreply.github.com>
Co-authored-by: Jamie Howard <jamie.howard@strapi.io>
Co-authored-by: mallowsc <mallowsc@outlook.com>
Co-authored-by: Jamie Howard <48524071+jhoward1994@users.noreply.github.com>
Co-authored-by: mallowsc <96073136+mallowsc@users.noreply.github.com>
Co-authored-by: Olli Hiekkaranta <Ohiekkar@users.noreply.github.com>
2024-09-02 14:31:01 +02:00

297 lines
9.8 KiB
JavaScript

'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 cwd = path.resolve(__dirname, '../..');
const testAppDirectory = path.join(cwd, 'test-apps', 'cli');
const testRoot = path.join(cwd, 'tests', 'cli');
const testsDir = path.join(testRoot, 'tests');
const templateDir = path.join(testRoot, 'app-template');
yargs
.parserConfiguration({
/**
* This lets us pass any other arguments to the test runner
* e.g. the name of a specific test or the project we want to run
*/
'unknown-options-as-args': false,
})
.command({
command: '*',
description: 'run the CLI test suite',
async builder(yarg) {
// each directory in testDir is a domain
const domains = await fs.readdir(testsDir);
yarg.option('concurrency', {
alias: 'c',
type: 'number',
default: domains.length,
describe: 'Number of concurrent test domains to run',
});
yarg.option('domains', {
alias: 'd',
describe: 'Run a specific test suite domain',
type: 'array',
choices: domains,
default: domains,
});
yarg.option('setup', {
alias: 'f',
describe: 'Force the setup process of the test apps',
type: 'boolean',
default: false,
});
},
async handler(argv) {
try {
const { concurrency, domains, setup } = argv;
/**
* Publishing all packages to the yalc store
*/
console.log('Running yalc...');
await execa('node', [path.join(__dirname, '../..', 'scripts', 'yalc-publish.js')]);
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 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
if (testAppsRequired === 0) {
throw new Error('No test apps to spawn');
}
const testAppPaths = Array.from({ length: testAppsRequired }, (_, i) =>
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
}
/**
* 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 < 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);
})
);
console.log(
`${chalk.green('Successfully')} setup test apps for the following domains: ${chalk.bold(
domains.join(', ')
)}`
);
} else {
console.log(
`Skipping setting up test apps, use ${chalk.bold('--setup')} to force the setup process`
);
}
/**
* 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);
console.log('Running jest for domain', domain, 'in', domainDir);
// run the command 'jest --rootDir <domainDir>'
await execa(
'jest',
[
'--config',
'../../../../jest.config.cli.js',
'--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`);
}
}
} catch (err) {
console.error(chalk.red('Error running CLI tests:'));
/**
* This is a ExecaError, if we were in TS we could do `instanceof`
*/
if (err.shortMessage) {
console.error(err.shortMessage);
process.exit(1);
}
console.error(err);
process.exit(1);
}
},
})
.command({
command: 'clean',
description: 'clean the test app directory of all test apps',
async handler() {
try {
const currentTestApps = await fs.readdir(testAppDirectory);
if (currentTestApps.length === 0) {
console.log('No test apps to clean');
return;
}
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);
})
);
} catch (err) {
console.error(chalk.red('Error cleaning test apps:'));
console.error(err);
process.exit(1);
}
},
})
.help()
.parse();