Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Workflow Training #195

Open
24 tasks
justinbmeyer opened this issue Jun 18, 2020 · 3 comments
Open
24 tasks

React Workflow Training #195

justinbmeyer opened this issue Jun 18, 2020 · 3 comments

Comments

@justinbmeyer
Copy link
Member

justinbmeyer commented Jun 18, 2020

As a React Trainer, I would like:

  • To have an example application to use as an example on various Design and Development workflows.

Workflows

Design Driven Development

Demonstrate a workflow for designers where:

  • They can contribute HTML + CSS (or SCSS, LESS)
  • That code can be readily used (ideally imported) by developers
  • The code doesn't get infected by development. This means that the output of designers can stay-as-is. This means things like {props.name} aren't inserted into HTML.
  • The code is sharable. Ideally, the CSS could be exported and consumed by other projects on its own.

Demonstrate how developers can take the Design work and make use of it. (This is really #2 above).

Modlet Development

Demonstrate a workflow for developers where:

  • They can readily create new components in isolation from the "main" application.
  • Those components should have a demo page.
  • Those components should have unit tests.
  • The component should be able to have styles (ideally imported from the Design work).
  • The demo page should be able to import other helpers (things like fixtures) to make the demo page work more easily.
  • The tests for the component should be able to be run without having to run other components tests.
  • Everything above should work without configuration (just create a folder).
  • The tests should be able to run even if there's a syntax error in code not used by those tests.
  • The demo page should be able to run even if there's a syntax error in the application (but not in code directly used by the demo).
  • The component should be able to have "localized" styles. Meaning the styles are not going to "leak" outside the component.
  • How to "publish" their storybook (gh-pages?)

Testing

Demonstrate a workflow for Developers (and or QE) where:

  • Unit tests are run as part of PRs.
  • Functional/Black Box (click, type, etc) tests run as part of PRs (Cypress?).
  • Snapshot testing is run as part of PRs.
  • Unit tests are run for every browser as part of PRs (Sauce Lab? CanJS uses this).
  • Functional/Black Box tests are run for every browser.
  • Snapshot testing is run for every browser.

Bonus Patterns?

Fixtures

Demonstrate a workflow for developers where:

  • Demo pages are able to use fixtures. (How does this work w/ GraphQL?)
  • Tests are able to use fixtures.
  • The application is able to use fixtures.

Steps

  1. Pick an application (TodoMVC, PlaceMyOrder).
  2. Create a new repo if necessary.
  3. Break out the app into multiple components if necessary.
  4. Setup CD and some basic unit tests (this will make sure we don't break the app while we continue development).
  5. Setup storybook.
  6. Get as many checkboxes checked as possible.
  7. Write up the workflow. (Where/how is tbd).
@dcrescim
Copy link
Contributor

dcrescim commented Jun 18, 2020

Thought I'd throw my thoughts down here to start the convo.

The easiest approach that we can take is probably a CRA + Storybook repo.
I've created an example todo app here. https://github.com/dcrescim/react-storybook-todo

Screen Shot 2020-06-18 at 2 03 15 PM

Screen Shot 2020-06-18 at 4 19 21 PM

Obviously the design can be made prettier before we hand it off to clients.

Let's go through the checkpoints starting at the top, and see how many it hits. I'm gonna start with the Modlet Development checklist. This repo uses the "Modlet" architecture that we use at Bitovi in other projects.

1. They can readily create new components in isolation from the "main" application.
We are good here. You can create components anywhere in the repo and they won't be pulled into the main app unless they are explicitly imported.

2. Those components should have a demo page.
Running yarn storybook makes the storybook "demo site" above. That site is the demo page.

3. Those components should have unit tests.
CRA comes with jest, and an example in App.test.js. Running yarn test will run your test suite.

4. The component should be able to have styles (ideally imported from the Design work).
Any component can simple import a CSS/LESS file, and then those styles are used locally. So as long as the design team puts their CSS/LESS somewhere in this repo we are good.

5. The demo page should be able to import other helpers (things like fixtures) to make the demo page work more easily.
Storybook comes with addons which allow you to mock actions events (button clicks, etc). Also every story is a javascript file so you can easily import any other code you want (fixtures, etc).

6. The tests for the component should be able to be run without having to run other components tests.
When you run yarn test it runs all of the tests and starts up watcher mode, but you can run a single test by doing yarn test -- -t 'test-name'

7. Everything above should work without configuration (just create a folder).
The CRA + Storybook is probably the lowest config solution (no wrangling with webpack, etc) for this use case. Just create a folder for a new component and in that folder you can write tests, stories, etc.

8. The tests should be able to run even if there's a syntax error in code not used by those tests.
Haven't tested this, but I'm 99% sure that the testing code will only run the *.test.js files. The bigger question is why they want this feature. Seems like a linter should catch these and they shouldn't ever be committed.

9. The demo page should be able to run even if there's a syntax error in the application (but not in code directly used by the demo).
I think this is the case here too, but seems like they shouldn't really be pushing code that has compile time issues at all.

10. The component should be able to have "localized" styles. Meaning the styles are not going to "leak" outside the component.
We should be good here. Any solution that uses a "CSS-in-JS" approach will be good here (styled-components, emotion, etc). Alternatively If they are absolutely wedded to css files we can just put them in the folder where we define the component, and import them from there. All of these solutions will be local to this component.

11. How to "publish" their storybook (gh-pages?)
Github pages and netlify are two easy-to-setup solutions that will work for the app / storybook.

@mikedane
Copy link
Contributor

mikedane commented Jun 19, 2020

Love the app/codebase @dcrescim!

I just submitted a PR with some additional features: https://github.com/dcrescim/react-storybook-todo/pull/1

The changes reinforce some of the already checked boxes, specifically I added a script to automatically generate component "modlets", and one to run the tests before code can be pushed.

I also added functional testing support with cypress (the tests themselves still need to be written, but the lib is setup), as-well as a script for running the tests in Github actions CI on push.

From the list above, I think we can comfortably check off the following sections:

  • Design Driven Development
  • Modlet Development
  • Testing
    • The only caveat here is with the snapshot testing. In my experience there's two types of snapshot testing that we might consider adding.
      • Snapshots that are run as part of the unit tests. These would essentially be snapshots of the DOM element tree that gets generated for each component. Basically we look at what the React components renders given a specific set of props. So it's just a file with the generated HTML that gets diffed (jest can do this easily - https://jestjs.io/docs/en/snapshot-testing)
      • The other type (which seems to be what's requested above) would be image snapshots for each major browser. I'm not sure Jest can do this, but there are some cypress plugins that support it. I haven't used any of these however so my ability to speak to their effectiveness is limited (https://docs.cypress.io/plugins/#visual-testing). @dcrescim do you have any experience with libs for this stuff?
  • Fixtures
    • Both Jest & Cypress support fixtures, and could both pull from the same mock data files for testing.
    • I'm not sure about GraphQL, but my guess is that it would be a pain to setup (we'd have to host a GraphQL server)

One question I do have: Is the client looking for recommendations on which libraries to use. For example, should we suggest a particular styling library? I also remember Brian mentioning that they're using Material Design, maybe we should re-design the TODO app to use something like https://material-ui.com/

A final consideration is migration. If I remember correctly, they're migrating an existing codebase from Angular to React? If so, it'd be nice to see their current setup, specifically around folder structure, CSS, and test data so that we can make more compatible suggestions.

Here's what I see as the next steps:

  • Decide on a solution for visual snapshot testing (see explanation above)
  • Write up some sort of README or short guide that walks through how to use the codebase.
    • One idea is to create a repo without any of the TODO code in it, and write a guide on how to create the TODO app using the "tools" we provide in the codebase.
  • Maybe flesh out the TODO app a bit more with some additional features.

@justinbmeyer
Copy link
Member Author

justinbmeyer commented Jun 22, 2020

  1. The tests should be able to run even if there's a syntax error in code not used by those tests.
    Haven't tested this, but I'm 99% sure that the testing code will only run the *.test.js files. The bigger question is why they want this feature. Seems like a linter should catch these and they shouldn't ever be committed.

This is proof that the tests can be run truly independently. In TypeScript reactors, having to keep the entire build working at all times was very difficult.

A less comprehensive version of this would be to make it so tests can run even if there's code like the following in another unrelated module:

import SomethingThatNoLongerHasAFuncMethod from "used-to-funk";

SomethingThatNoLongerHasAFuncMethod.funk();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants