Tested live documentation is a thing with MDX, Docz and Cypress
You can quickly write live interactive component documentation and make sure it works as expected by testing it.
I love documenting things. I hate when my documentation is out of date. For unit tests I have built a tool called xplain to convert unit tests into Markdown examples to be included in README. But what about UI components? Turns out you can have an interactive documentation for your components with a new tool called docz that is just a pleasure to use. Currently docz supports only React components, but support for other frameworks might be coming.
Live documentation with Docz
docz uses MDX document format which is a Markdown enhanced with JSX. If you want to see Docz in action, take a look at the short intro video by clicking the link below the image.
Great, so we can write component documentation really quickly, and our documentation site is interactive! Take a look at the example repo bahmutov/cy-docz - just a couple of components, with Button component showing "onClick" handler that does "alert" message. Clone the repo, start the docz server with npm run dev and open localhost:3000 - the documentation is live
Here is the relevant part from the Button.mdx
1 2 3 4 5 6 7 8 9 10 11 12 13
--- name: Button menu: Components ---
import { Playground } from 'docz' import Button from './Button'
Tip: you can create "index" page by creating a MDX file with "route /" meta setting.
1 2 3 4 5 6 7
--- name: Index page route: / order: 1 ---
This will be the index page
And now let us make sure our documentation is never out of date with respect to the source component. We will test it - we will add end-to-end tests to our live documentation using the Cypress.io test runner.
Testing documentation
I will place my spec files right in components folder to be next to the source code Button.jsx and its documentation Button.mdx files.
And I will point Cypress to load *-spec.js files from this folder, while ignoring .jsx or .mdx files using cypress.json configuration file. I also set the viewport width to be wide to avoid Docz menu covering the buttons (docz output is not yet responsive)
Here is a test to confirm the documentation page shows alert message when the user clicks the button. The test assumes the docz size is running locally via npm run dev command.
When we run this test it ... shows no alert dialog, because Cypress automatically intercepts it.
But you can still see that the Button documentation behaves as expected - the Cypress command list shows the stubbed invocation.
Great! We can sleep better knowing that our documentation is really working. You can find a few more tests I wrote against Button.mdx in components/Button-spec.js
Running tests
How can we run docz and test it quickly? We need to start the docz server, wait for it to finish bundling (it might take a few seconds even for small projects), then run Cypress tests. There is a utility start-server-and-test I wrote that makes it easy. After installing it as a dev dependency, here are my package scripts
I just need to execute npm test to make sure my documentation is correct
docz is using webpack dev server under the hood, which does not reply to HEAD requests. Thus I need to use GET requests to ping the server to know when it's ready. Thus the url to ping is http-get://localhost:3000 and not simply http://localhost:3000
βΆ start Creating an optimized production build... β success Compiled successfully.
File sizes after gzip:
138.67 KB dist/static/js/vendors.360b5044.js 1.36 KB dist/static/js/components-button.d13b64c5.js 1.15 KB dist/static/js/runtime~app.0f53f534.js 1023 B dist/static/js/components-alert.b0a4263a.js 950 B dist/static/js/app.7db074eb.js
We can deploy the docs to GitHub pages using gh-pages. Here are the relevant scripts from package.json, and because I plan to host the docs at https://glebbahmutov.com/cy-docz I need to pass base parameter so that all resources are prefixed with /cy-docz in the generated HTML
You can see the deployed documentation at https://glebbahmutov.com/cy-docz url. Best feature - we can test the deployed documentation just to make sure the build process did not break our documentation (that would be awful, right?)
So we add one more command to our package.json file to run Cypress tests against the public site by passing baseUrl as a CLI argument - check out the script "test-deployed" below:
package.json
1 2 3 4 5 6 7 8 9 10 11 12
{ "scripts":{ "test":"start-test dev http-get://localhost:3000 cy:run", "test-deployed":"cypress run --config baseUrl=https://glebbahmutov.com/cy-docz", "dev":"docz dev", "build":"docz build --base /cy-docz/", "cy:open":"cypress open", "cy:run":"cypress run", "predeploy":"npm run build", "deploy":"gh-pages -d .docz/dist" } }
After each deploy we validate the documentation using Cypress
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$ npm run test-deployed
> [email protected] test-deployed /Users/gleb/git/cy-docz > cypress run --config baseUrl=https://glebbahmutov.com/cy-docz
Running: Button-spec.js... (1 of 1)
Button β shows on the docz page (1099ms) β shows alert on click (1953ms)
2 passing (3s)
Great, live interactive documentation that is tested with very little effort - just use docz and Cypress together.