Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Improvement of tests script to allow param passing (Issue/3472) #3478

Merged
merged 16 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ node_modules
.DS_Store
.idea
coverage
.vscode
2 changes: 1 addition & 1 deletion grunt/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ module.exports = function(grunt) {
// add root path if necessary, and point to course/config.json

const configPath = path.join(path.resolve(root, configDir), coursedir, 'config.' + jsonext);

let buildConfig;

try {
buildConfig = grunt.file.readJSON(configPath).build || {};
} catch (error) {
Expand Down
12 changes: 6 additions & 6 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,14 @@ module.exports = {

// The glob patterns Jest uses to detect test files
testMatch: [
'**/test/unit/**/*.js?(x)',
'!**/__mocks__/**/*.js?(x)'
]
'**/test/unit/**/*.js?(x)'
],

// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
testPathIgnorePatterns: [
'/__mocks__/',
'/node_modules/'
]

// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
Expand Down
2 changes: 1 addition & 1 deletion src/core
87 changes: 67 additions & 20 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,19 @@ async function waitForExec(command, ...args) {
return await new Promise(resolve => exec([command, ...args].join(' '), { stdio: [0, 1, 2] }, resolve));
}

const shouldUseOutputDir = Boolean(process.env.npm_config_outputdir);
const outputDir = (process.env.npm_config_outputdir || './build/');

async function hasInstalledAndBuilt() {
const hasInstalled = await doFilesExist([
async function hasInstalled() {
return await doFilesExist([
'src/components/*',
'src/extensions/*',
'src/menu/*',
'src/theme/*'
]);
const hasBuilt = await doFilesExist([
path.join(outputDir, 'index.html')
};

async function hasBuilt() {
return await doFilesExist([
path.join(argumentValues.outputdir, 'index.html')
]);
return hasInstalled && hasBuilt;
};

async function adaptInstall() {
Expand All @@ -69,42 +68,70 @@ async function gruntDiff() {
'node',
'./node_modules/grunt/bin/grunt',
'diff',
shouldUseOutputDir && `--outputdir=${outputDir}`
Boolean(process.env.npm_config_outputdir) && `--outputdir=${argumentValues.outputdir}`
].filter(Boolean));
};

async function gruntServer() {
return backgroundSpawn('node', './node_modules/grunt/bin/grunt', 'server-silent', 'run', `--outputdir=${outputDir}`);
return backgroundSpawn('node', './node_modules/grunt/bin/grunt', 'server-silent', 'run', `--outputdir=${argumentValues.outputdir}`);
};

async function waitForGruntServer() {
return waitForExec('node', './node_modules/wait-on/bin/wait-on', 'http://localhost:9001');
};

async function cypressRun() {
if (argumentValues.testfiles) {
return asyncSpawn('node', './node_modules/cypress/bin/cypress', 'run', '--spec', `${argumentValues.testfiles}`);
}

return asyncSpawn('node', './node_modules/cypress/bin/cypress', 'run');
};

async function jestRun() {
config.testEnvironmentOptions.outputDir = outputDir;
config.testEnvironmentOptions.outputDir = argumentValues.outputdir;

// Limit the tests if a certain set are passed in
if (argumentValues.testfiles) {
config.testMatch = argumentValues.testfiles.split(',');
}

return jest.runCLI(config, [process.cwd().replace(/\\/g, '/')]);
oliverfoster marked this conversation as resolved.
Show resolved Hide resolved
};

async function jestClear() {
return asyncSpawn('node', './node_modules/jest/bin/jest', '--clearCache');
};

const acceptedArgs = [
'outputdir',
'skipinstall',
'testfiles'
];

const argumentValues = {
outputdir: (process.env.npm_config_outputdir || './build/'),
skipinstall: false,
testfiles: null
};

const commands = {
help: {
name: 'help',
description: 'Display this help screen',
async start() {
console.log(`
const helpText = `
Usage:

To run prepare with the unit and then e2e tests:
$ npm test

To run prepare with the unit and then e2e tests without overwriting the ./src/ plugins:
$ npm test --skipinstall

To run prepare with specif unit and/or e2e tests:
$ npm test --testfiles=**/globForTestsToRun/**

To run any of the available commands:
$ npm test <command>

Expand All @@ -114,15 +141,22 @@ Usage:
where <command> is one of:

${Object.values(commands).map(({ name, description }) => ` ${name.padEnd(21, ' ')}${description}`).join('\n')}
`);
`;
console.log(helpText);
}
},
prepare: {
name: 'prepare',
description: 'Install and build Adapt ready for testing (runs automatically when requied)',
async start() {
await adaptInstall();
await gruntDiff();
if ((argumentValues.skipinstall !== 'true') && !await hasInstalled()) {
console.log('Installing latest adapt plugins');
await adaptInstall();
}
if (!await hasBuilt()) {
console.log(`Performing course build to '${argumentValues.outputdir}'`);
await gruntDiff();
}
}
},
e2e: {
Expand Down Expand Up @@ -159,26 +193,39 @@ ${Object.values(commands).map(({ name, description }) => ` ${name.padEnd(21,
const runTest = async () => {
const parameters = process.argv.slice(2);
const hasParameters = Boolean(parameters.length);
const [ commandName ] = parameters;
let [ passedArgs = '' ] = parameters;
const [ commandName ] = passedArgs.split(' ');
const command = commands[commandName];
const isCommandNotFound = !command;

// Read the input for passed arguments that arent command names
passedArgs = passedArgs.trim().replaceAll('--', '').toLowerCase().split(' ').filter(name => isCommandNotFound || name !== commandName);

// Update argumentValues array for later use while checking if the command is valid
const paramsRecognised = passedArgs.every(passedArg => {
const passedArgParts = passedArg.trim().split('=');
argumentValues[passedArgParts[0]] = passedArgParts[1];
oliverfoster marked this conversation as resolved.
Show resolved Hide resolved
return acceptedArgs.includes(passedArgParts[0]);
});

try {
if (isCommandNotFound && hasParameters) {
const e = new Error(`Unknown command "${commandName}", please check the documentation. $ npm test help`);
if (isCommandNotFound && hasParameters && !paramsRecognised) {
const e = new Error(`Unknown command/argument "${parameters[0]}", please check the documentation. $ npm test help`);
console.error(e);
return;
}

const isCommandHelp = (commandName === 'help');
const isCommandPrepare = (commandName === 'prepare');
const shouldPrepare = (isCommandPrepare || (!isCommandHelp && !await hasInstalledAndBuilt()));
const shouldPrepare = (isCommandPrepare || !isCommandHelp);

if (shouldPrepare) {
await commands.prepare.start();
if (isCommandPrepare) return;
}

if (!hasParameters) {
// No specific command called - run tests by default
if (isCommandNotFound) {
await commands.unit.start();
await commands.e2e.start();
process.exit(0);
Expand Down