UNPKG

storybook-chromatic

Version:

Visual Testing for Storybook

90 lines (78 loc) 2.37 kB
import { spawn } from 'child_process'; import fetch from 'isomorphic-fetch'; import path from 'path'; const CHECK_EVERY = 1000; const TIMEOUT = 5 * 60 * 1000; export async function checkResponse(url) { try { await fetch(url); return true; } catch (e) { return false; } } async function waitForResponse(child, url) { const timeoutAt = Date.now() + TIMEOUT; return new Promise((resolve, reject) => { let resolved = false; async function check() { if (Date.now() > timeoutAt) { resolved = true; reject(new Error(`No server responding at ${url} within ${TIMEOUT / 1000} seconds.`)); return; } if (await checkResponse(url)) { resolved = true; resolve(); return; } setTimeout(check, CHECK_EVERY); } check(); if (child) { let output = ''; child.stderr.on('data', e => { output += e.toString(); }); child.stdout.on('data', o => { output += o.toString(); }); child.on('close', () => { if (!resolved) { reject(new Error(`Script failed to start: ${output}\n`)); } }); } }); } export default async function startApp({ scriptName, commandName, url }) { const env = { ...process.env, NODE_ENV: 'development', BROWSER: 'none', }; let child; if (scriptName) { if (await checkResponse(url)) { // We assume the process that is already running on the url is indeed our storybook return null; } // This technique lifted from https://github.com/mysticatea/npm-run-all/blob/52eaf86242ba408dedd015f53ca7ca368f25a026/lib/run-task.js#L156-L174 const npmPath = process.env.npm_execpath; const npmPathIsJs = typeof npmPath === 'string' && /\.m?js/.test(path.extname(npmPath)); const execPath = npmPathIsJs ? process.execPath : npmPath || 'npm'; // Run either: // npm/yarn run scriptName (depending on npm_execpath) // node path/to/npm.js run scriptName (if npm run via node) child = spawn(execPath, [...(npmPathIsJs ? [npmPath] : []), 'run', scriptName], { env, }); } else { if (!commandName) { throw new Error('You must pass commandName or scriptName'); } child = spawn(commandName, { env, shell: true }); } await waitForResponse(child, url); return child; }