Giter Site home page Giter Site logo

mattcosta7 / msw-storybook-addon Goto Github PK

View Code? Open in Web Editor NEW

This project forked from mswjs/msw-storybook-addon

0.0 0.0 0.0 1003 KB

Mock API requests in Storybook with Mock Service Worker.

Home Page: https://msw-sb.vercel.app

License: MIT License

JavaScript 74.58% TypeScript 6.30% CSS 2.25% HTML 3.61% MDX 13.25%

msw-storybook-addon's Introduction

MSW Storybook Addon

Features

  • Mock Rest and GraphQL requests right inside your story.
  • Document how a component behaves in various scenarios.
  • Get a11y, snapshot and visual tests using other addons for free.

Full documentation and live demos

Installing and Setup

Install MSW and the addon

With npm:

npm i msw msw-storybook-addon -D

Or with yarn:

yarn add msw msw-storybook-addon -D

Generate service worker for MSW in your public folder.

If you already use MSW in your project, you have likely done this before so you can skip this step.

npx msw init public/

Refer to the MSW official guide for framework specific paths if you don't use public.

Configure the addon

Enable MSW in Storybook by initializing MSW and providing the MSW decorator in ./storybook/preview.js:

import { initialize, mswLoader } from 'msw-storybook-addon';

// Initialize MSW
initialize();

const preview = {
  parameters: { 
    // your other code...
  },
  // Provide the MSW addon loader globally
  loaders: [mswLoader],
}

export default preview

Start Storybook

When running Storybook, you have to serve the public folder as an asset to Storybook, so that MSW is included, otherwise it will not be available in the browser.

This means you should set the staticDirs field in the Storybook main config file. Refer to the docs if needed.

npm run start-storybook

Usage

You can pass request handlers (https://mswjs.io/docs/basics/request-handler) into the handlers property of the msw parameter. This is commonly an array of handlers.

import { rest } from 'msw'

export const SuccessBehavior = () => <UserProfile />

SuccessBehavior.parameters = {
  msw: {
    handlers: [
      rest.get('/user', (req, res, ctx) => {
        return res(
          ctx.json({
            firstName: 'Neil',
            lastName: 'Maverick',
          })
        )
      }),
    ]
  },
}

Advanced Usage

Composing request handlers

The handlers property can also be an object where the keys are either arrays of handlers or a handler itself. This enables you to inherit (and optionally overwrite/disable) handlers from preview.js using parameter inheritance:

type MswParameter = {
  handlers: RequestHandler[] | Record<string, RequestHandler | RequestHandler[]>
}

Suppose you have an application where almost every component needs to mock requests to /login and /logout the same way. You can set global MSW handlers in preview.js for those requests and bundle them into a property called auth, for example:

//preview.js

// These handlers will be applied in every story
export const parameters = {
   msw: {
      handlers: {
        auth: [
           rest.get('/login', (req, res, ctx) => {
              return res(
                ctx.json({
                   success: true,
                })
              )
           }),
           rest.get('/logout', (req, res, ctx) => {
              return res(
                ctx.json({
                   success: true,
                })
              )
           }),
        ],
      }
   }
};

Then, you can use other handlers in your individual story. Storybook will merge both global handlers and story handlers:

// This story will include the auth handlers from preview.js and profile handlers
SuccessBehavior.parameters = {
  msw: {
   handlers: {
    profile: rest.get('/profile', (req, res, ctx) => {
      return res(
       ctx.json({
        firstName: 'Neil',
        lastName: 'Maverick',
       })
      )
    }),
   }
  }
}

Now suppose you want to ovewrite the global handlers for auth. All you have to do is set them again in your story and these values will take precedence:

// This story will overwrite the auth handlers from preview.js
FailureBehavior.parameters = {
  msw: {
   handlers: {
    auth: rest.get('/login', (req, res, ctx) => {
      return res(ctx.status(403))
    }),
   }
  }
}

What if you want to disable global handlers? All you have to do is set them as null and they will be ignored for your story:

// This story will disable the auth handlers from preview.js
NoAuthBehavior.parameters = {
  msw: {
   handlers: {
    auth: null,
    others: [
      rest.get('/numbers', (req, res, ctx) => {
       return res(ctx.json([1, 2, 3]))
      }),
      rest.get('/strings', (req, res, ctx) => {
       return res(ctx.json(['a', 'b', 'c']))
      }),
    ],
   }
  }
}

Configuring MSW

msw-storybook-addon starts MSW with default configuration. initialize takes two arguments:

A common example is to configure the onUnhandledRequest behavior, as MSW logs a warning in case there are requests which were not handled.

If you want MSW to bypass unhandled requests and not do anything:

// preview.js
import { initialize } from 'msw-storybook-addon';

initialize({
  onUnhandledRequest: 'bypass'
})

If you want to warn a helpful message in case stories make requests that should be handled but are not:

// preview.js
import { initialize } from 'msw-storybook-addon';

initialize({
  onUnhandledRequest: ({ method, url }) => {
    if (url.pathname.startsWith('/my-specific-api-path')) {
      console.error(`Unhandled ${method} request to ${url}.

        This exception has been only logged in the console, however, it's strongly recommended to resolve this error as you don't want unmocked data in Storybook stories.

        If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses
      `)
    }
  },
})

Although composing handlers is possible, that relies on Storybook's merging logic, which currently only works when the handlers in your story's parameters are objects and not arrays. To get around this limitation, you can pass initial request handlers directly the initialize function as a second argument.

// preview.js
import { initialize } from 'msw-storybook-addon';

initialize({}, [
  rest.get('/numbers', (req, res, ctx) => {
    return res(ctx.json([1, 2, 3]))
  }),
  rest.get('/strings', (req, res, ctx) => {
    return res(ctx.json(['a', 'b', 'c']))
  }),
])

Troubleshooting

MSW is interfering with HMR (Hot Module Replacement)

If you're experiencing issues like [MSW] Failed to mock a "GET" request to "http://localhost:6006/4cb31fa2eee22cf5b32f.hot-update.json" in the console, it's likely that MSW is interfering with HMR. This is not common and it seems to only happen in Webpack projects, but if it happens to you, you can follow the steps in this issue to fix it:

mswjs#36 (comment)

msw-storybook-addon's People

Contributors

itaditya avatar yannbf avatar kettanaito avatar jesusthehun avatar coderkevin avatar adwd avatar oscard0m avatar rajtslegr avatar sethdavenport avatar sivli-embir avatar stevensacks avatar will-stone avatar pentzzsolt avatar jonniebigodes avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.