Skip to content

Latest commit

 

History

History
207 lines (143 loc) · 7.62 KB

DEVELOPING.md

File metadata and controls

207 lines (143 loc) · 7.62 KB

Development Setup

Our development setup assumes a LINUX/BSD environment.

Project Setup

  1. Install Node v22 nvm install && nvm use.
  2. Install Yarn package manager https://yarnpkg.com/en/docs/install v1.10 or higher.
  3. Fork the upstream repo https://github.com/box/box-ui-elements via github.
  4. Clone your fork locally git clone git@github.com:[YOUR GITHUB USERNAME]/box-ui-elements.git.
  5. Navigate to the cloned folder cd box-ui-elements.
  6. Add the upstream repo to your remotes git remote add upstream git@github.com:box/box-ui-elements.git.
  7. Verify your remotes are properly set up git remote -v. You should pull updates from the upstream box repo and push changes to your fork origin.

Storybook

We use Storybook (https://storybook.js.org/). A published version of our Storybook is available at https://opensource.box.com/box-ui-elements/.

Local Development

  1. Start your local Storybook instance via yarn start.
  2. Navigate to http://localhost:6060/ to see the UI Elements in action. If testing on a different machine or VM, you can instead use the IP address shown on your terminal window.

Testing UI Elements in a Parent Project

Webpack Setup

box-ui-elements must use the same react and react-dom instances as the parent application for React hooks to work properly. Application repositories must add the following webpack resolve alias configuration to satisfy this requirement:

// webpack.config.js
{
    ...
    resolve: {
        alias: {
            'react': path.resolve('node_modules/react'),
            'react-dom': path.resolve('node_modules/react-dom'),
        }
    }
    ...
}

This will ensure that box-ui-elements does not use its own react and react-dom modules when linked. Improper setup is the primary reason for "Invalid Hook" errors due to React version mismatch.

We also recommend using yarn resolutions to fix the version of react and react-dom in your application:

// package.json
{
    ...
    "resolutions": {
        "react": "17.0.1",
        "react-dom": "17.0.1"
    },
    ...
}

Linking box-ui-elements

To test the Box UI Elements with your own project use local Yarn linking.

  1. In the UI Elements project run yarn link as a one time setup.
  2. In UI Elements project run yarn start:npm which starts a local npm build in watch mode.
  3. In your parent project run yarn link box-ui-elements every time you plan to use the local linked version.
  4. Run your parent project's build.

Common Script Commands

  • yarn start to launch a local Storybook server. Uses demo live data for Elements.
  • yarn start:npm to symlink Elements via yarn link to a parent project.
  • yarn lint to lint js and css.
  • yarn lint:js --fix to lint js and fix issues.
  • yarn lint:css --fix to lint styles and fix issues.
  • yarn test to launch tests with jest.
  • yarn test --watch to launch tests with jest in watch mode.
  • yarn test --coverage to launch tests with jest with coverage.
  • yarn test:visual to run the visual regression tests locally (requires Docker). See Visual Regression Testing.
  • yarn test:visual:download <pull request number | branch> to apply the baselines regenerated by CI for a pull request.
  • yarn release to run a release.

For more script commands see package.json. Test coverage reports are available under reports/coverage.

Best Practices

import * as React from 'react'

You should always use this syntax over import React, { ... } from 'react' because it automatically includes flow types.

Consequently, you must use the React prefix for related functions and components.

  • Component => React.Component
  • useState => React.useState

For more information, please see https://flow.org/en/docs/react/components/#toc-class-components

Useful Plugins

Install the following plugins in your preferred editor

  • Editor Config (standardizes basic editor configuration)
  • ESLint (JavaScript linting)
  • Stylelint (CSS linting)
  • Prettier (JavaScript formatting)
  • Sass (Stylesheets)
  • Babel (Transpiler)

Unit Testing

Jest and Enzyme

The project uses the jest testing framework and enzyme for component testing.

Please refer to the relevant documentation pages for tutorials and troubleshooting:

Testing Hooks with Enzyme

Most hooks can be tested with shallow rendering except for lifecycle hooks such as useEffect and useLayoutEffect.

To test a useEffect hook, you must use act() from react-dom/test-utils and mount() from enzyme.

import { act } from 'react';

test('something happens', () => {
    let wrapper;

    // Perform initial render
    act(() => {
        wrapper = mount(<SomeComponent foo="bar">Content</SomeComponent>);
    });

    // Assert
    expect(wrapper...);

    // Perform re-render
    act(() => {
        // Update props to exercise lifecycle methods
        wrapper.setProps({
            foo: 'baz'
        });
    });

    // Update wrapper - This must be after act()
    wrapper.update();

    // Assert
    expect(wrapper...);
})

See React Testing Recipes for more examples.

Visual Regression Testing

Visual stories (*-visual.stories.*) are being migrated from Chromatic to Playwright screenshot tests. Each migrated story is rendered from the production Storybook build and compared with a committed baseline PNG in test/visual/__screenshots__/<Element>/<story-name>-linux.png. The comparison is strict: any pixel that differs beyond the colour threshold fails the story.

In CI

The CircleCI visual-tests job runs scripts/visual_tests.sh on every pull request. It is skipped when the branch only changes files that cannot affect rendering (docs, repo metadata, Cypress specs, and Jest tests; see scripts/visual_changes.sh).

When screenshots differ, the job fails, regenerates the changed baselines, and prints a link to the Playwright report with the before/after diffs. If the changes are intended, apply the regenerated baselines from the repo root and commit them:

yarn test:visual:download <pull request number | branch>

Locally

Baselines are rendered on Linux, so the local run uses the same Playwright Docker image as CI. Start Docker, then run:

yarn test:visual

This builds Storybook and runs the tests. Set VISUAL_SKIP_BUILD=1 to reuse an existing storybook/ build. When screenshots differ, the changed baselines are rewritten in your working tree and a link to the report is printed. Review them with git diff, then either commit them with your change or restore them:

git checkout -- test/visual/__screenshots__ && git clean -fd test/visual/__screenshots__

The pre-commit hook reminds you to run yarn test:visual when a commit stages src/ files that may affect rendering and no baselines. It never blocks the commit.

Migrating a Story File off Chromatic

  1. Add the file to MIGRATED_STORY_FILES in test/visual/storybook.spec.ts.
  2. Remove chromatic: { disableSnapshot: false } from its parameters.
  3. Run yarn test:visual to generate the baselines and commit them.

The spec fails if a migrated file is missing from the Storybook index, still opts in to Chromatic, or has two stories that would share a screenshot name within an element.

Troubleshooting

Python

gyp verb check python checking for Python executable "/usr/bin/python" in the PATH
gyp verb `which` failed Error: not found: /usr/bin/python
  1. Ensure you have Python 2 installed
  2. Get the location of your Python installation via which python
  3. yarn config set python /path/to/python