feat(web): add validate:storybook script (build, serve 6007, audit)
This commit is contained in:
parent
2119833779
commit
4dcae6ca00
2 changed files with 102 additions and 1 deletions
|
|
@ -52,7 +52,8 @@
|
||||||
"storybook": "cross-env VITE_API_URL=/api/v1 VITE_USE_MSW=true VITE_STORYBOOK=true storybook dev -p 6006",
|
"storybook": "cross-env VITE_API_URL=/api/v1 VITE_USE_MSW=true VITE_STORYBOOK=true storybook dev -p 6006",
|
||||||
"build-storybook": "cross-env VITE_API_URL=/api/v1 VITE_USE_MSW=true VITE_STORYBOOK=true storybook build",
|
"build-storybook": "cross-env VITE_API_URL=/api/v1 VITE_USE_MSW=true VITE_STORYBOOK=true storybook build",
|
||||||
"test:storybook": "node scripts/audit-storybook.js",
|
"test:storybook": "node scripts/audit-storybook.js",
|
||||||
"test:storybook:playwright": "playwright test --config=playwright.config.storybook.ts"
|
"test:storybook:playwright": "playwright test --config=playwright.config.storybook.ts",
|
||||||
|
"validate:storybook": "node scripts/validate-storybook.cjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
|
|
|
||||||
100
apps/web/scripts/validate-storybook.cjs
Normal file
100
apps/web/scripts/validate-storybook.cjs
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* validate-storybook: build Storybook, serve on 6007, run audit, then stop server.
|
||||||
|
* Single command for CI/local: npm run validate:storybook
|
||||||
|
*/
|
||||||
|
const { spawn, execSync } = require('child_process');
|
||||||
|
const http = require('http');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const PORT = 6007;
|
||||||
|
const INDEX_URL = `http://localhost:${PORT}/index.json`;
|
||||||
|
const POLL_MS = 500;
|
||||||
|
const POLL_TIMEOUT_MS = 60000;
|
||||||
|
|
||||||
|
function waitForUrl(url, timeoutMs) {
|
||||||
|
const start = Date.now();
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const tryOnce = () => {
|
||||||
|
const req = http.get(url, (res) => {
|
||||||
|
if (res.statusCode === 200) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.resume();
|
||||||
|
schedule();
|
||||||
|
});
|
||||||
|
req.on('error', () => schedule());
|
||||||
|
req.setTimeout(5000, () => {
|
||||||
|
req.destroy();
|
||||||
|
schedule();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const schedule = () => {
|
||||||
|
if (Date.now() - start > timeoutMs) {
|
||||||
|
reject(new Error(`Timeout waiting for ${url}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(tryOnce, POLL_MS);
|
||||||
|
};
|
||||||
|
tryOnce();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runBuild() {
|
||||||
|
console.log('[validate-storybook] Running build-storybook...');
|
||||||
|
execSync('npm run build-storybook', {
|
||||||
|
stdio: 'inherit',
|
||||||
|
cwd: path.resolve(__dirname, '..'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const cwd = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
|
runBuild();
|
||||||
|
|
||||||
|
const serve = spawn('npx', ['serve', 'storybook-static', '-l', String(PORT)], {
|
||||||
|
stdio: 'pipe',
|
||||||
|
shell: true,
|
||||||
|
cwd,
|
||||||
|
});
|
||||||
|
|
||||||
|
let auditExitCode = 1;
|
||||||
|
serve.on('error', (err) => {
|
||||||
|
console.error('[validate-storybook] Failed to start serve:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
waitForUrl(INDEX_URL, POLL_TIMEOUT_MS)
|
||||||
|
.then(() => {
|
||||||
|
console.log('[validate-storybook] Server ready, running audit...');
|
||||||
|
const audit = spawn('node', ['scripts/audit-storybook.js'], {
|
||||||
|
stdio: 'inherit',
|
||||||
|
shell: true,
|
||||||
|
cwd,
|
||||||
|
});
|
||||||
|
return new Promise((res) => {
|
||||||
|
audit.on('exit', (code) => {
|
||||||
|
auditExitCode = code ?? 1;
|
||||||
|
res();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('[validate-storybook]', err.message);
|
||||||
|
auditExitCode = 1;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
serve.kill('SIGTERM');
|
||||||
|
serve.on('exit', () => {
|
||||||
|
process.exit(auditExitCode);
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
serve.kill('SIGKILL');
|
||||||
|
process.exit(auditExitCode);
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
Loading…
Reference in a new issue