2021-11-19 21:02:02 +00:00
|
|
|
#!/usr/bin/env node
|
|
|
|
|
|
|
|
/**
|
|
|
|
* External dependencies.
|
|
|
|
*/
|
|
|
|
const fs = require( 'fs' );
|
2021-12-08 23:38:45 +00:00
|
|
|
const path = require( 'path' );
|
2021-11-19 21:02:02 +00:00
|
|
|
const sprintf = require( 'sprintf-js' ).sprintf;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Internal dependencies.
|
|
|
|
*/
|
2021-11-26 20:55:22 +00:00
|
|
|
const {
|
|
|
|
resolvePackage,
|
|
|
|
resolvePackagePath,
|
|
|
|
} = require( '../utils' );
|
2021-12-08 20:56:53 +00:00
|
|
|
const {
|
|
|
|
createLocalE2ePath,
|
|
|
|
confirm,
|
|
|
|
confirmLocalCopy,
|
2021-12-08 23:08:29 +00:00
|
|
|
confirmLocalDelete,
|
|
|
|
getPackageData,
|
2022-01-06 15:02:05 +00:00
|
|
|
installDefaults,
|
2021-12-08 20:56:53 +00:00
|
|
|
} = require( '../utils/scaffold' );
|
2021-11-19 21:02:02 +00:00
|
|
|
|
2021-11-26 20:55:22 +00:00
|
|
|
const args = process.argv.slice( 2 );
|
2022-01-26 16:13:18 +00:00
|
|
|
const command = args[0];
|
|
|
|
let packageName = null;
|
2022-01-26 16:36:39 +00:00
|
|
|
|
2022-02-03 23:36:18 +00:00
|
|
|
if ( args[1] && args[1].substr(0, 2) !== '--' ) {
|
2022-01-26 16:13:18 +00:00
|
|
|
packageName = args[1];
|
|
|
|
}
|
2021-11-19 21:02:02 +00:00
|
|
|
|
2021-12-08 23:08:29 +00:00
|
|
|
// Allow multiple spec file extensions and formats.
|
|
|
|
let testExtension = 'test.js';
|
|
|
|
let testFormat = '';
|
2022-01-26 16:13:18 +00:00
|
|
|
let force = false;
|
2022-01-26 16:27:25 +00:00
|
|
|
for ( let a = 1; a < args.length; a++ ) {
|
|
|
|
if (args[a] === '--force') {
|
|
|
|
force = true;
|
|
|
|
continue;
|
|
|
|
}
|
2022-01-26 16:13:18 +00:00
|
|
|
|
2022-01-26 16:27:25 +00:00
|
|
|
// These arguments take a value, eg: --format foo
|
|
|
|
const nextArg = a + 1;
|
|
|
|
if ( nextArg >= args.length ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch ( args[ a ] ) {
|
2021-12-08 23:08:29 +00:00
|
|
|
case '--format':
|
2022-01-26 16:27:25 +00:00
|
|
|
testFormat = args[ nextArg ];
|
2021-12-08 23:08:29 +00:00
|
|
|
break;
|
|
|
|
case '--ext':
|
2022-01-26 16:27:25 +00:00
|
|
|
testExtension = args[ nextArg ];
|
2021-12-08 23:08:29 +00:00
|
|
|
break;
|
|
|
|
}
|
2022-01-26 16:27:25 +00:00
|
|
|
}
|
2021-12-08 23:08:29 +00:00
|
|
|
|
2021-11-19 21:02:02 +00:00
|
|
|
/**
|
|
|
|
* Install the test scripts and sample default.json configuration
|
|
|
|
*/
|
|
|
|
if ( command == 'install' ) {
|
2021-12-08 20:56:53 +00:00
|
|
|
// Install some environment defaults if no package is requested.
|
|
|
|
if ( ! packageName ) {
|
2022-01-26 16:27:25 +00:00
|
|
|
installDefaults(force);
|
2021-12-08 20:56:53 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-08 17:47:30 +00:00
|
|
|
// `package` is a reserved word
|
|
|
|
const pkg = resolvePackage( packageName ).name;
|
|
|
|
if ( ! pkg.length ) {
|
2021-11-26 20:55:22 +00:00
|
|
|
//@todo add error message
|
|
|
|
return;
|
2021-11-19 21:02:02 +00:00
|
|
|
}
|
2021-12-08 23:08:29 +00:00
|
|
|
const { packageSlug, testSpecs, defaultJson, initializeSh } = getPackageData( pkg );
|
2021-11-19 21:02:02 +00:00
|
|
|
|
|
|
|
// Write sample default.json
|
2021-11-26 20:55:22 +00:00
|
|
|
if ( defaultJson ) {
|
2021-12-08 23:38:45 +00:00
|
|
|
const defaultJsonName = `config${path.sep}default-${packageSlug}.json`;
|
2021-12-08 23:08:29 +00:00
|
|
|
createLocalE2ePath( 'config' );
|
2022-01-26 16:27:25 +00:00
|
|
|
if ( confirmLocalCopy( defaultJsonName, defaultJson, pkg, force ) ) {
|
2021-12-08 20:56:53 +00:00
|
|
|
console.log( `Created sample test configuration to 'tests/e2e/${defaultJsonName}'.` );
|
|
|
|
}
|
2021-11-26 20:55:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Write sample initialize.sh
|
|
|
|
if ( initializeSh ) {
|
2021-12-08 23:38:45 +00:00
|
|
|
const defaultInitName = `docker${path.sep}${packageSlug}.sh`;
|
2021-12-08 23:08:29 +00:00
|
|
|
createLocalE2ePath( 'docker' );
|
2022-01-26 16:27:25 +00:00
|
|
|
if ( confirmLocalCopy( defaultInitName, initializeSh, pkg, force ) ) {
|
2021-12-08 20:56:53 +00:00
|
|
|
console.log( `Created sample test container initialization script to 'tests/e2e/${defaultInitName}'.` );
|
|
|
|
}
|
2021-11-26 20:55:22 +00:00
|
|
|
}
|
2021-11-19 21:02:02 +00:00
|
|
|
|
2021-11-26 20:55:22 +00:00
|
|
|
if ( ! testSpecs ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-08 19:12:27 +00:00
|
|
|
// Write test files
|
2021-12-08 17:47:30 +00:00
|
|
|
const testsSpecFile = resolvePackagePath( testSpecs, pkg );
|
2021-11-26 20:55:22 +00:00
|
|
|
const specs = fs.readFileSync( testsSpecFile );
|
|
|
|
const tests = JSON.parse( specs );
|
|
|
|
const { active, deprecated } = tests;
|
|
|
|
|
|
|
|
if ( active && active.length ) {
|
2021-12-08 17:47:30 +00:00
|
|
|
const blankLine = '';
|
2021-11-19 21:02:02 +00:00
|
|
|
const eol = "\n";
|
2021-12-09 21:08:48 +00:00
|
|
|
const autoGenerate = sprintf( '/* This file was auto-generated by the command `npx wc-e2e install %s`. */', packageName );
|
2021-11-26 20:55:22 +00:00
|
|
|
let importLineFormat;
|
2021-12-08 19:12:27 +00:00
|
|
|
let confirmPrompt;
|
2021-11-26 20:55:22 +00:00
|
|
|
if ( testFormat.toLowerCase() == 'cjs' ) {
|
2021-12-08 17:47:30 +00:00
|
|
|
importLineFormat = sprintf( "const {%%s} = require( '%s' );", pkg );
|
2021-11-26 20:55:22 +00:00
|
|
|
} else {
|
2021-12-08 17:47:30 +00:00
|
|
|
importLineFormat = sprintf( "import {%%s} from '%s';", pkg );
|
2021-11-26 20:55:22 +00:00
|
|
|
}
|
2022-02-03 23:47:14 +00:00
|
|
|
let overwriteFiles;
|
|
|
|
if (force) {
|
|
|
|
overwriteFiles = 'a';
|
|
|
|
}
|
2021-11-26 20:55:22 +00:00
|
|
|
|
2021-12-08 20:56:53 +00:00
|
|
|
// Create the specs folder if not present
|
|
|
|
let specFolderPath = createLocalE2ePath( 'specs' );
|
2021-12-08 17:47:30 +00:00
|
|
|
|
2021-11-19 21:02:02 +00:00
|
|
|
// Loop through folders and files to write test scripts.
|
2021-11-26 20:55:22 +00:00
|
|
|
for ( let f = 0; f < active.length; f++ ) {
|
2021-12-08 19:12:27 +00:00
|
|
|
if ( overwriteFiles == 'q' ) {
|
|
|
|
overwriteFiles = '';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-11-26 20:55:22 +00:00
|
|
|
const testFolder = active[ f ];
|
|
|
|
const { testFiles } = testFolder;
|
|
|
|
|
|
|
|
if ( ! testFiles || ! testFiles.length ) {
|
2021-11-19 21:02:02 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-12-08 20:56:53 +00:00
|
|
|
let specFolder;
|
|
|
|
if ( testFolder.name.length ) {
|
2021-12-08 23:38:45 +00:00
|
|
|
specFolder = createLocalE2ePath( `specs${path.sep}${testFolder.name}` );
|
2021-12-08 20:56:53 +00:00
|
|
|
} else {
|
|
|
|
specFolder = specFolderPath;
|
2021-11-19 21:02:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create the test files.
|
2021-11-26 20:55:22 +00:00
|
|
|
for ( let t = 0; t < testFiles.length; t++ ) {
|
|
|
|
const testFile = testFiles[ t ];
|
2021-11-19 21:02:02 +00:00
|
|
|
if ( ! testFile.functions.length ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-12-08 23:38:45 +00:00
|
|
|
const testFileName = `${testFolder.name}${path.sep}${testFile.name}.${testExtension}`;
|
|
|
|
const testFilePath = `${specFolder}${path.sep}${testFile.name}.${testExtension}`;
|
2021-11-19 21:02:02 +00:00
|
|
|
|
2021-12-08 19:12:27 +00:00
|
|
|
// Check to see if file exists.
|
|
|
|
if ( fs.existsSync( testFilePath ) ) {
|
|
|
|
if ( overwriteFiles != 'a' ) {
|
2021-12-08 23:08:29 +00:00
|
|
|
confirmPrompt = `${testFileName} already exists. Overwrite? [y]es/[n]o/[a]ll/[q]uit: `;
|
2021-12-08 19:12:27 +00:00
|
|
|
overwriteFiles = confirm( confirmPrompt, 'anqy' );
|
|
|
|
overwriteFiles = overwriteFiles.toLowerCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( overwriteFiles == 'q' ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( overwriteFiles != 'a' && overwriteFiles != 'y' ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2021-11-19 21:02:02 +00:00
|
|
|
|
2021-12-08 20:56:53 +00:00
|
|
|
console.log( 'Writing tests/e2e/specs/' + testFileName );
|
2021-11-19 21:02:02 +00:00
|
|
|
let buffer = [ autoGenerate ];
|
|
|
|
let testSeparator, testTerminator, importPrefix;
|
|
|
|
|
|
|
|
// Add the import line.
|
|
|
|
if ( testFile.functions.length > 3 ) {
|
|
|
|
testSeparator = ',' + eol;
|
|
|
|
testTerminator = eol;
|
|
|
|
importPrefix = eol;
|
|
|
|
} else {
|
|
|
|
testSeparator = ', ';
|
2021-12-08 17:47:30 +00:00
|
|
|
testTerminator = ' ';
|
2021-11-19 21:02:02 +00:00
|
|
|
importPrefix = ' ';
|
|
|
|
}
|
|
|
|
const testImport = testFile.functions.join( testSeparator ) + testTerminator;
|
2021-12-08 17:47:30 +00:00
|
|
|
buffer.push( sprintf( importLineFormat, importPrefix + testImport ), blankLine );
|
2021-11-19 21:02:02 +00:00
|
|
|
|
|
|
|
// Add test function calls and write the file
|
|
|
|
let functionCalls = testFile.functions.map( functionName => functionName + '();' );
|
2021-12-08 17:47:30 +00:00
|
|
|
buffer.push( ...functionCalls, blankLine );
|
2021-11-19 21:02:02 +00:00
|
|
|
fs.writeFileSync( testFilePath, buffer.join( eol ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-26 20:55:22 +00:00
|
|
|
// @todo: deprecated files.
|
2021-12-08 23:08:29 +00:00
|
|
|
} else if ( command == 'uninstall' ) {
|
|
|
|
if ( ! packageName ) {
|
|
|
|
// @todo: write error message
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const pkg = resolvePackage( packageName ).name;
|
|
|
|
const { packageSlug, testSpecs, defaultJson, initializeSh } = getPackageData( pkg );
|
|
|
|
|
|
|
|
// Delete sample default.json
|
|
|
|
if ( defaultJson ) {
|
2021-12-08 23:38:45 +00:00
|
|
|
const defaultJsonName = `config${path.sep}default-${packageSlug}.json`;
|
2021-12-08 23:08:29 +00:00
|
|
|
confirmLocalDelete( defaultJsonName );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete sample initialize.sh
|
|
|
|
if ( initializeSh ) {
|
2021-12-08 23:38:45 +00:00
|
|
|
const defaultInitName = `docker${path.sep}${packageSlug}.sh`;
|
2021-12-08 23:08:29 +00:00
|
|
|
confirmLocalDelete( defaultInitName );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ! testSpecs ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const testsSpecFile = resolvePackagePath( testSpecs, pkg );
|
|
|
|
const specs = fs.readFileSync( testsSpecFile );
|
|
|
|
const tests = JSON.parse( specs );
|
2021-12-08 23:38:45 +00:00
|
|
|
const { active } = tests;
|
2021-12-08 23:08:29 +00:00
|
|
|
|
|
|
|
if ( ! active || ! active.length ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Loop through folders and files to delete test scripts.
|
|
|
|
for ( let f = 0; f < active.length; f++ ) {
|
|
|
|
const testFolder = active[ f ];
|
|
|
|
const { testFiles } = testFolder;
|
|
|
|
|
|
|
|
if ( ! testFiles || ! testFiles.length ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-12-08 23:38:45 +00:00
|
|
|
const specFolder = testFolder.name.length ? `specs${path.sep}${testFolder.name}` : 'specs';
|
2021-12-08 23:08:29 +00:00
|
|
|
for ( let t = 0; t < testFiles.length; t++ ) {
|
|
|
|
const testFile = testFiles[ t ];
|
2021-12-08 23:38:45 +00:00
|
|
|
const testFilePath = `${specFolder}${path.sep}${testFile.name}.${testExtension}`;
|
2021-12-08 23:08:29 +00:00
|
|
|
|
|
|
|
confirmLocalDelete( testFilePath );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-19 21:02:02 +00:00
|
|
|
}
|