RFC: Interactions
Inspired by the upcoming StorybookJS Interaction Testing, I am thinking of introducing something similar to React Showroom.
Goals
- Allow docs viewer to see a sequence of interactions in browser directly
Must-have
- use
testing-libraryas the programmatic way to run simulations.
Nice-to-have
- Allowing reusing code for the interaction demo and tests, following our philosophy of reusing existing dev workflow instead of reinvent one.
- Undo/redo the interaction steps
- Ability to run the interaction step-by-step
Challenges
- Because we're using markdown instead of javascript, it is probably challenging to achieve nice-to-have 1.
Note: Storybook instruments (monkey-patch) @testing-library methods so they can intercept it.
Intention of trying to reuse code for interaction with tests feel clunky as we need to define the interactions outside of the markdown file, but the interactions is dependent on the rendered content.
Reference: https://github.com/malcolm-kee/react-showroom/tree/feature/run-fn
Preview: https://61d092d22bc6cbe65a4e48a7--react-showroom-subpath.netlify.app/some-subpath/button/#usestate-example
Thinking out loud: maybe parse jest tests and then run it in browser???
After playing around with esbuild, now I have better idea how to do this:
- combining
acornandesbuild, create a file from component test file that will export each test with a function name generated deterministically from the test name. The dependencies of the file will be prebundled (except few libraries, e.g.reactand@testing-libraryand those listed inimports.) (Possible improvement: if it's import the components, maybe just resolve to the component instead). - component metadata will include a key-value object of
{ [testName]: fnName }that allows us to generate a path pointing to a specificfnNameassociated with a test. - an
InteractionBlockcomponent will be exported fromreact-showroom/clientwhich will accepts atestNameprops. The component will use the props in combination of the key-value object above to generates a path, e.g./_interactions/:componentId/:fnNamethat will be used as url ofiframe. - we will create another sub app - interaction app (in addition of current showroom app and preview app) that will parse the path and use it to import specific test file and run. This app will be run in
iframerendered byInteractionBlock. The reason we want to run this asiframeis to isolate as much as possible (although we can't do it fully). - For
build, we also need to prerender the interaction app so the html will be generated for static site hosting. - [To explore] Inject
@testing-library/*usage with custom code, that will allows us to send details about the interactions from interaction app to showroom app, thus enabling play/pause feature like storybookjs.