Skip to content

Commit

Permalink
feat: Expose react-styleguidist screenshot binary (#1203)
Browse files Browse the repository at this point in the history
feat: Expose react-styleguidist screenshot binary
  • Loading branch information
ptbrowne authored Oct 17, 2019
2 parents 40b4798 + 6fcd254 commit 93891e4
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 9 deletions.
4 changes: 3 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build
.travis.yml
renovate.json
yarn.lock
/scripts

.changelog
examples
docs
Expand All @@ -21,3 +21,5 @@ loaders
# Since parcel users will use the transpiled version of cozy-ui
# that has already been processed by postcss, it is not necessary.
postcss.config.js

screenshots/
22 changes: 22 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,26 @@ yarn build:doc:react
yarn deploy:doc --repo [email protected]:USERNAME/cozy-ui.git
```
## UI regression testing
Components in `cozy-ui` are showcased with [React Styleguidist][]. To prevent UI regressions,
for each PR, each component is screenshotted and compared to the master version to find any
regression (thanks [Argos][] !).
If your app uses [React Styleguidist][], `cozy-ui` provides `rsg-screenshots`, a CLI tool to take
screenshots of your components (uses Puppeteer under the hood).
```bash
$ yarn add cozy-ui
$ # The rsg-screenshots binary is now installed
$ yarn build:doc:react # Build our styleguide, the output directory is docs/react
$ rsg-screenshots --screenshot-dir screenshots/ --styleguide-dir docs/react
# Each component in the styleguide will be screenshotted and saved inside the
# screenshots/ directory
```
See our [travis configuration](./travis.yml) for more information.
## License
Cozy UI is developed by Cozy Cloud and distributed under the AGPL-3.0 license.
Expand All @@ -107,3 +127,5 @@ You can reach the Cozy Community by:
* Mentioning us on [Twitter](https://twitter.com/cozycloud)
[stylus]: http://stylus-lang.com/
[React Styleguidist]: https://react-styleguidist.js.org/
[Argos]: https://github.com/argos-ci/argos
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"version": "0.0.0-development",
"description": "Cozy apps UI SDK",
"main": "./index.js",
"bin": {
"rsg-screenshots": "./scripts/screenshots.js"
},
"repository": {
"type": "git",
"url": "https://github.com/cozy/cozy-ui.git"
Expand Down Expand Up @@ -42,7 +45,7 @@
"semantic-release": "semantic-release",
"sprite": "scripts/make-icon-sprite.sh",
"jest": "yarn test:jest",
"screenshots": "node scripts/screenshots.js",
"screenshots": "node scripts/screenshots.js --screenshot-dir ./screenshots --styleguide-dir ./build/react",
"test": "yarn test:jest",
"test:jest": "jest --verbose",
"transpile": "env BABEL_ENV=transpilation babel react/ --out-dir transpiled/react --verbose",
Expand Down Expand Up @@ -133,6 +136,7 @@
"react-select": "2.2.0"
},
"peerDependencies": {
"puppeteer": "1.20.0",
"@material-ui/core": "3.9.3",
"cozy-client": "*",
"cozy-device-helper": "1.7.5",
Expand Down
36 changes: 29 additions & 7 deletions scripts/screenshots.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
const puppeteer = require('puppeteer')
#!/usr/bin/env node

let puppeteer
try {
puppeteer = require('puppeteer')
} catch (e) {
console.error(e)
console.log('Could not import puppeteer, you should install it if you want to take screenshots')
process.exit(1)
}
const path = require('path')
const fs = require('fs')
const sortBy = require('lodash/sortBy')
const { ArgumentParser } = require('argparse')

const emptyDirectory = directory => {
for (const filename of fs.readdirSync(directory)) {
Expand Down Expand Up @@ -95,22 +105,34 @@ const prepareBrowser = async () => {
return { browser, page }
}

const pathArgument = p => {
if (p.startsWith('/')) {
return p
} else {
return path.join(process.cwd(), p)
}
}

/**
* Fetches all components from styleguide and takes a screenshot of each.
*/
const main = async () => {
const SCREENSHOT_DIR = path.join(__dirname, '../screenshots')
const STYLEGUIDE_DIR = path.join(__dirname, '../build/react')

await prepareFS(STYLEGUIDE_DIR, SCREENSHOT_DIR)
const parser = new ArgumentParser()

parser.addArgument('--screenshot-dir', { required: true, dest: 'screenshotDir', type: pathArgument })
parser.addArgument('--styleguide-dir', { required: true, dest: 'styleguideDir', type: pathArgument })

const args = parser.parseArgs()

await prepareFS(args.styleguideDir, args.screenshotDir)
const { browser, page } = await prepareBrowser()

const styleguideIndexURL = `file://${STYLEGUIDE_DIR}/index.html`
const styleguideIndexURL = `file://${path.join(args.styleguideDir, '/index.html')}`
const components = await fetchAllComponents(page, styleguideIndexURL)

console.log('Screenshotting all components')
for (const component of components) {
await screenshotComponent(page, component, SCREENSHOT_DIR)
await screenshotComponent(page, component, args.screenshotDir)
}

await browser.close()
Expand Down

0 comments on commit 93891e4

Please sign in to comment.