mirror of
https://github.com/storybookjs/storybook.git
synced 2025-03-16 05:03:11 +08:00
125 lines
3.7 KiB
JavaScript
Executable File
125 lines
3.7 KiB
JavaScript
Executable File
import { spawn } from 'child_process';
|
|
import { promisify } from 'util';
|
|
import { readdir as readdirRaw, readFileSync, existsSync } from 'fs';
|
|
import { join } from 'path';
|
|
import program from 'commander';
|
|
import prompts from 'prompts';
|
|
import chalk from 'chalk';
|
|
|
|
import { getDeployables } from './utils/list-examples';
|
|
import { filterDataForCurrentCircleCINode } from './utils/concurrency';
|
|
|
|
program
|
|
.option(
|
|
'--skip <value>',
|
|
'Skip an example, accepts multiple values like "--skip vue-kitchen-sink official-storybook"',
|
|
(value, previous) => previous.concat([value]),
|
|
[]
|
|
)
|
|
.option('--all', `run e2e tests for every example`, false);
|
|
program.parse(process.argv);
|
|
|
|
const { all: shouldRunAllExamples, args: exampleArgs, skip: examplesToSkip } = program;
|
|
|
|
const readdir = promisify(readdirRaw);
|
|
|
|
const p = (l) => join(__dirname, '..', ...l);
|
|
const logger = console;
|
|
|
|
const exec = async (command, args = [], options = {}) =>
|
|
new Promise((resolve, reject) => {
|
|
const child = spawn(command, args, { ...options, stdio: 'inherit', shell: true });
|
|
|
|
child
|
|
.on('close', (code) => {
|
|
if (code) {
|
|
reject();
|
|
} else {
|
|
resolve();
|
|
}
|
|
})
|
|
.on('error', (e) => {
|
|
logger.error(e);
|
|
reject();
|
|
});
|
|
});
|
|
|
|
// TODO think if this filter is what we want for smoke tests
|
|
const hasBuildScript = (l) => {
|
|
const text = readFileSync(l, 'utf8');
|
|
const json = JSON.parse(text);
|
|
|
|
return !!json.scripts['build-storybook'];
|
|
};
|
|
|
|
const handleExamples = async (deployables) => {
|
|
await deployables.reduce(async (acc, d) => {
|
|
await acc;
|
|
|
|
logger.log('');
|
|
logger.log(`-----------------${Array(d.length).fill('-').join('')}`);
|
|
logger.log(`▶️ smoke-testing: ${d}`);
|
|
logger.log(`-----------------${Array(d.length).fill('-').join('')}`);
|
|
const cwd = p(['examples', d]);
|
|
|
|
// ensure web-components example works, because it's outside the yarn workspace
|
|
if (existsSync(join(cwd, 'yarn.lock'))) {
|
|
await exec(`yarn`, [`install`], { cwd });
|
|
}
|
|
|
|
await exec(`yarn`, ['storybook', '--smoke-test', '--quiet'], { cwd });
|
|
|
|
logger.log('-------');
|
|
logger.log(`✅ ${d} passed`);
|
|
logger.log('-------');
|
|
}, Promise.resolve());
|
|
};
|
|
|
|
const run = async () => {
|
|
const allExamples = await readdir(p(['examples']));
|
|
|
|
// if a specific example is passed, use it. Else use all
|
|
let examplesToBuild =
|
|
exampleArgs.length > 0
|
|
? exampleArgs
|
|
: allExamples.filter((example) => !example.includes('README'));
|
|
|
|
if (examplesToSkip.length > 0) {
|
|
logger.log(`⏭ Will skip the following examples: ${chalk.yellow(examplesToSkip.join(', '))}`);
|
|
examplesToBuild = examplesToBuild.filter((example) => !examplesToSkip.includes(example));
|
|
}
|
|
|
|
if (!shouldRunAllExamples && exampleArgs.length === 0) {
|
|
const { selectedExamples } = await prompts([
|
|
{
|
|
type: 'autocompleteMultiselect',
|
|
message: 'Select the examples to smoke-test',
|
|
name: 'selectedExamples',
|
|
min: 1,
|
|
hint: 'You can also run directly with example name like `yarn smoketest-storybooks official-example`, or `yarn smoketest-storybooks --all` for all examples!',
|
|
choices: examplesToBuild.map((exampleName) => {
|
|
return {
|
|
value: exampleName,
|
|
title: exampleName,
|
|
selected: false,
|
|
};
|
|
}),
|
|
},
|
|
]);
|
|
examplesToBuild = selectedExamples;
|
|
}
|
|
|
|
const list = getDeployables(examplesToBuild, hasBuildScript);
|
|
const deployables = filterDataForCurrentCircleCINode(list);
|
|
|
|
if (deployables.length) {
|
|
logger.log(`🏗 Will smoke test: ${chalk.cyan(deployables.join(', '))}`);
|
|
await handleExamples(deployables);
|
|
}
|
|
};
|
|
|
|
run().catch((e) => {
|
|
logger.error(e);
|
|
process.exit(1);
|
|
});
|