-
-
Notifications
You must be signed in to change notification settings - Fork 27k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Automate screencast recordings * **screencast.js**: Automate screencast.sh, asciinema, svg-term-cli. Removes progress-bar, npm tree data from cast * **screencast.sh**: Simulate user input, trigger demoed commands * **screencast-start.js**: Start a shell command and end the process log patterns have been observed
- Loading branch information
Showing
4 changed files
with
173 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const execa = require('execa'); | ||
const meow = require('meow'); | ||
const multimatch = require('multimatch'); | ||
|
||
main(meow()); | ||
|
||
function main(cli) { | ||
let count = 0; | ||
|
||
const start = Date.now(); | ||
const duration = parseInt(cli.flags.timeout, 10) * 1000; | ||
const cp = execa.shell(cli.flags.command); | ||
|
||
const target = parseInt(cli.flags.patternCount || '1', 10); | ||
|
||
cp.stdout.on('data', data => { | ||
process.stdout.write(data); | ||
const matches = multimatch([String(data)], cli.flags.pattern); | ||
const errMatches = multimatch([String(data)], cli.flags.errorPattern); | ||
|
||
if (matches.length > 0) { | ||
count++; | ||
} | ||
|
||
if (errMatches.length > 0) { | ||
process.exit(1); | ||
} | ||
|
||
if (count >= target) { | ||
setTimeout(() => { | ||
process.exit(0); | ||
}, duration); | ||
} | ||
}); | ||
|
||
cp.on('exit', e => { | ||
const elapsed = Date.now() - start; | ||
|
||
if (elapsed >= duration) { | ||
return; | ||
} | ||
|
||
setTimeout(() => { | ||
process.exit(e.code); | ||
}, duration - elapsed); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#!/usr/bin/env node | ||
|
||
/** | ||
* Copyright (c) 2015-present, Facebook, Inc. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
const fs = require('fs'); | ||
const path = require('path'); | ||
const execa = require('execa'); | ||
const tempy = require('tempy'); | ||
|
||
main(); | ||
|
||
function main() { | ||
const previous = process.cwd(); | ||
const cwd = tempy.directory(); | ||
|
||
const cast = path.join(cwd, 'screencast.json'); | ||
const script = path.join(__dirname, 'screencast.sh'); | ||
const out = path.join(previous, 'screencast.svg'); | ||
|
||
const resolveLine = l => l.indexOf('🔍 Resolving packages...') > -1; | ||
const fetchLine = l => l.indexOf('🚚 Fetching packages...') > -1; | ||
const countLine = l => l.match(/Saved [0-9]+ new dependencies/); | ||
const doneLine = l => l.indexOf('✨ Done in') > -1; | ||
|
||
try { | ||
process.chdir(cwd); | ||
console.log(`Recording screencast ...`); | ||
execa.sync('asciinema', ['rec', '--command', `sh ${script}`, cast], { | ||
cwd, | ||
stdio: 'inherit', | ||
}); | ||
|
||
console.log('Cleaning data ...'); | ||
const data = require(cast); | ||
|
||
cut(data.stdout, { start: resolveLine, end: fetchLine }); | ||
cut(data.stdout, { start: countLine, end: doneLine }); | ||
replace(data.stdout, [{ in: cwd, out: '~' }]); | ||
|
||
fs.writeFileSync(cast, JSON.stringify(data, null, ' ')); | ||
|
||
console.log('Rendering SVG ...'); | ||
execa.sync('svg-term', ['--window', '--in', cast, '--out', out]); | ||
|
||
console.log(`Recorded screencast to ${cast}`); | ||
console.log(`Rendered SVG to ${out}`); | ||
} catch (err) { | ||
throw err; | ||
} finally { | ||
process.chdir(previous); | ||
} | ||
} | ||
|
||
function cut(frames, { start, end }) { | ||
const si = frames.findIndex(([, l]) => start(l)); | ||
const ei = frames.findIndex(([, l]) => end(l)); | ||
|
||
if (si === -1 || ei === -1) { | ||
return; | ||
} | ||
|
||
frames.splice(si + 1, ei - si - 1); | ||
} | ||
|
||
function replace(frames, replacements) { | ||
frames.forEach(frame => { | ||
replacements.forEach(r => (frame[1] = frame[1].split(r.in).join(r.out))); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/bin/zsh | ||
# Copyright (c) 2015-present, Facebook, Inc. | ||
# | ||
# This source code is licensed under the MIT license found in the | ||
# LICENSE file in the root directory of this source tree. | ||
|
||
# ****************************************************************************** | ||
# This is an end-to-end test intended to be run via screencast.js | ||
# Dependencies: asciinema, pv, core-utils | ||
# ****************************************************************************** | ||
set -e | ||
|
||
printf '\e[32m%s\e[m' "λ " | ||
echo "npx create-react-app my-app" | pv -qL $[10+(-2 + RANDOM%5)] | ||
npx create-react-app my-app | ||
|
||
printf '\e[32m%s\e[m' "λ " | ||
sleep 1 | ||
echo "cd my-app" | pv -qL $[10+(-2 + RANDOM%5)] | ||
cd my-app | ||
|
||
printf '\e[32m%s\e[m' "λ " | ||
sleep 1 | ||
echo "npm start" | pv -qL $[10+(-2 + RANDOM%5)] | ||
|
||
BROWSER="none" node "$(dirname $0)/screencast-start.js" \ | ||
--command "npm start" \ | ||
--pattern="Compiled successfully*" \ | ||
--pattern-count 2 \ | ||
--error-pattern="*already running on port" \ | ||
--timeout 10 | ||
|
||
echo "" |