Skip to content

Commit

Permalink
feat: add coverage panel
Browse files Browse the repository at this point in the history
  • Loading branch information
yannbf committed Jun 15, 2022
1 parent 703a8f4 commit 2b5d377
Show file tree
Hide file tree
Showing 31 changed files with 2,206 additions and 1,811 deletions.
1 change: 1 addition & 0 deletions .babelrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
"@babel/preset-typescript",
"@babel/preset-react",
],
ignore: ["./src/typings.d.ts"],
env: {
esm: {
presets: [
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ node_modules/
storybook-static/
build-storybook.log
.DS_Store
.env
.env
yarn-*.log
12 changes: 11 additions & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,15 @@ module.exports = {
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)",
],
addons: ["../preset.js", "@storybook/addon-essentials"],
addons: [
{
name: "../preset.js",
options: { useExternalInstrumentation: false }
},
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
features: {
interactionsDebugger: true
}
};
90 changes: 3 additions & 87 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,92 +1,8 @@
# Storybook Addon Addon coverage
Tools to support code coverage in Storybook
# Storybook Addon Coverage

Tools to support code coverage in Storybook and the [test runner](https://github.com/storybookjs/test-runner)

### Development scripts

- `yarn start` runs babel in watch mode and starts Storybook
- `yarn build` build and package your addon code

### Switch from TypeScript to JavaScript

Don't want to use TypeScript? We offer a handy eject command: `yarn eject-ts`

This will convert all code to JS. It is a destructive process, so we recommended running this before you start writing any code.

## What's included?

![Demo](https://user-images.githubusercontent.com/42671/107857205-e7044380-6dfa-11eb-8718-ad02e3ba1a3f.gif)

The addon code lives in `src`. It demonstrates all core addon related concepts. The three [UI paradigms](https://storybook.js.org/docs/react/addons/addon-types#ui-based-addons)

- `src/Tool.js`
- `src/Panel.js`
- `src/Tab.js`

Which, along with the addon itself, are registered in `src/preset/manager.js`.

Managing State and interacting with a story:

- `src/withGlobals.js` & `src/Tool.js` demonstrates how to use `useGlobals` to manage global state and modify the contents of a Story.
- `src/withRoundTrip.js` & `src/Panel.js` demonstrates two-way communication using channels.
- `src/Tab.js` demonstrates how to use `useParameter` to access the current story's parameters.

Your addon might use one or more of these patterns. Feel free to delete unused code. Update `src/preset/manager.js` and `src/preset/preview.js` accordingly.

Lastly, configure you addon name in `src/constants.js`.

### Metadata

Storybook addons are listed in the [catalog](https://storybook.js.org/addons) and distributed via npm. The catalog is populated by querying npm's registry for Storybook-specific metadata in `package.json`. This project has been configured with sample data. Learn more about available options in the [Addon metadata docs](https://storybook.js.org/docs/react/addons/addon-catalog#addon-metadata).

## Release Management

### Setup

This project is configured to use [auto](https://github.com/intuit/auto) for release management. It generates a changelog and pushes it to both GitHub and npm. Therefore, you need to configure access to both:

- [`NPM_TOKEN`](https://docs.npmjs.com/creating-and-viewing-access-tokens#creating-access-tokens) Create a token with both _Read and Publish_ permissions.
- [`GH_TOKEN`](https://github.com/settings/tokens) Create a token with the `repo` scope.

Then open your `package.json` and edit the following fields:

- `name`
- `author`
- `repository`

#### Local

To use `auto` locally create a `.env` file at the root of your project and add your tokens to it:

```bash
GH_TOKEN=<value you just got from GitHub>
NPM_TOKEN=<value you just got from npm>
```

Lastly, **create labels on GitHub**. You’ll use these labels in the future when making changes to the package.

```bash
npx auto create-labels
```

If you check on GitHub, you’ll now see a set of labels that `auto` would like you to use. Use these to tag future pull requests.

#### GitHub Actions

This template comes with GitHub actions already set up to publish your addon anytime someone pushes to your repository.

Go to `Settings > Secrets`, click `New repository secret`, and add your `NPM_TOKEN`.

### Creating a release

To create a release locally you can run the following command, otherwise the GitHub action will make the release for you.

```sh
yarn release
```

That will:

- Build and package the addon code
- Bump the version
- Push a release to GitHub and npm
- Push a changelog to GitHub
20 changes: 20 additions & 0 deletions babel-plugin-source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = function ({ types: t }) {
return {
visitor: {
ExportDefaultDeclaration: {
enter({ node }) {
// set default.parameters.coverage
/**
* {
* coverage: {
* fileName: '',
* filePath: '',
* source: '' <- raw source
* }
* }
*/
},
},
},
};
};
25 changes: 16 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
"version": "0.0.0",
"description": "Tools to support code coverage in Storybook",
"keywords": [
"storybook-addons", "coverage", "test", "testing", "test-runner", "storybook-addons"
"storybook-addons",
"coverage",
"test",
"testing",
"test-runner",
"storybook-addons"
],
"repository": {
"type": "git",
Expand Down Expand Up @@ -43,27 +48,29 @@
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.5",
"@babel/preset-typescript": "^7.13.0",
"@storybook/addon-essentials": "^6.4.0",
"@storybook/react": "^6.4.0",
"@storybook/addon-essentials": "^6.5.9",
"@storybook/addon-interactions": "^6.5.9",
"@storybook/react": "^6.5.9",
"@storybook/testing-library": "^0.0.12",
"auto": "^10.3.0",
"babel-loader": "^8.1.0",
"boxen": "^5.0.1",
"concurrently": "^6.2.0",
"dedent": "^0.7.0",
"prettier": "^2.3.1",
"prop-types": "^15.7.2",
"raw-loader": "^4.0.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"rimraf": "^3.0.2",
"typescript": "^4.2.4",
"zx": "^1.14.1"
},
"peerDependencies": {
"@storybook/addons": "^6.4.0",
"@storybook/api": "^6.4.0",
"@storybook/components": "^6.4.0",
"@storybook/core-events": "^6.4.0",
"@storybook/theming": "^6.4.0",
"@storybook/addons": "^6",
"@storybook/api": "^6",
"@storybook/components": "^6",
"@storybook/core-events": "^6",
"react": "^16.8.0 || ^17.0.0",
"react-dom": "^16.8.0 || ^17.0.0"
},
Expand All @@ -81,7 +88,7 @@
"storybook": {
"displayName": "Addon coverage",
"supportedFrameworks": [
"react", "vue", "angular", "web-components", "ember", "html", "svelte", "preact", "react-native"
"react"
],
"icon": "https://user-images.githubusercontent.com/321738/63501763-88dbf600-c4cc-11e9-96cd-94adadc2fd72.png"
}
Expand Down
26 changes: 26 additions & 0 deletions preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,33 @@ function managerEntries(entry = []) {
return [...entry, require.resolve("./dist/esm/preset/manager")];
}

const defaultIstanbulOptions = {
cwd: __dirname,
exclude: [
"**/*.d.ts",
"**/*{.,-}{spec,stories,types}.{js,jsx,ts,tsx}",
]
}

const babel = async (babelConfig, options) => {
if (options.useExternalInstrumentation) {
return babelConfig
}

babelConfig.plugins.push(
[
"istanbul",
{
...defaultIstanbulOptions,
...options.istanbul,
},
],
)
return babelConfig
};

module.exports = {
managerEntries,
config,
babel
};
36 changes: 0 additions & 36 deletions src/Panel.tsx

This file was deleted.

15 changes: 0 additions & 15 deletions src/Tab.tsx

This file was deleted.

31 changes: 0 additions & 31 deletions src/Tool.tsx

This file was deleted.

47 changes: 47 additions & 0 deletions src/components/CoveragePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

import React from 'react';
import { useChannel, useAddonState } from '@storybook/api';
import { SyntaxHighlighter } from '@storybook/components';

import { ADDON_ID, EVENTS } from '../constants';
import { CoverageDetail } from '../types';
import { lineCoverage } from '../utils';

interface DetailPanelProps {
detail: CoverageDetail;
}

const DetailPanel: React.FC<DetailPanelProps> = ({ detail }) => {
if (!(detail.source && detail.item)) {
return <div>No coverage set</div>;
}

const lineToMissing = lineCoverage(detail.item);
const lineProps = (lineNumber: number) =>
lineToMissing[lineNumber] ? { style: { backgroundColor: '#ffcccc', borderLeft: '5px solid #f85151' } } : { style: { borderLeft: '5px solid #95de95' } };
return (
<SyntaxHighlighter
language="jsx"
showLineNumbers
// @ts-ignore
wrapLines
// @ts-ignore
lineProps={lineProps}
format={false}
copyable={false}
padded
>
{detail.source}
</SyntaxHighlighter>
);
};

export const CoveragePanel: React.VFC = () => {
const [coverageDetail, setCoverageDetail] = useAddonState<CoverageDetail>(ADDON_ID, null);

useChannel({
[EVENTS.COVERAGE_DETAIL]: (detail: CoverageDetail) => setCoverageDetail(detail),
});

return coverageDetail ? <DetailPanel detail={coverageDetail} /> : <div>No coverage</div>;
};
Loading

0 comments on commit 2b5d377

Please sign in to comment.