Msw: Using MSW with Karma

Created on 5 Nov 2020  路  15Comments  路  Source: mswjs/msw

Environment

| Name | Version |
| ------- | ------- |
| msw | 0.21.3 |
| browser | Chrome Headless 86.0.4240.183 |
| OS | Mac OS 10.15.6 |

Request handlers

Added custom header to make sure the service worker is allowed.

// karma.conf.js
const path = require( 'path' );

module.exports = function( config ){
    config.set( {
        basePath: path.resolve( '.' ),
        frameworks: [ 'mocha', 'chai' ],
        client: {
            chai: { includeStack: true },
            mocha: { ui: 'bdd' }
        },
        customHeaders: [
            {
                match: '.*.html',
                name: 'Service-Worker-Allowed',
                value: '/'
            }
        ],
        files: [
            `test/**/${ specs }.spec.js`
        ],
        browsers: [ 'ChromeHeadless' ],
        singleRun: true
    } );
};

All files are located in /test including mockServiceWorker.js, installed via npx msw init test.

// handlers.js
const { rest } = require( 'msw' );

export const handlers = [
    rest.get( '/foo', async ( response, request, context ) => response( context.json( { foo: 123 } ) ) )
];

```js
// worker.js
const { setupWorker } = require( 'msw' );
import { handlers } from './handlers';

export const worker = setupWorker( ...handlers );


## Actual request

<!-- Reference how do you perform a request (i.e. fetch/axios/etc.) -->

```js
// foo.spec.js
const { expect } = require( 'chai' );
import { worker } from './worker';

describe( 'Fetching foo', function(){
    this.beforeAll( () => worker.start() );
    this.afterAll( () => worker.stop() );

    it( 'should handle foo', function(){
        return fetch( '/foo' ).then( ( response ) => response.json() ).then( function( data ){
            expect( data ).to.deep.equal( { foo: 123 } );
        } );
    } );
} );

Current behavior

ERROR: '[MSW] Failed to register a Service Worker for scope ('http://localhost:9876/') with script ('http://localhost:9876/mockServiceWorker.js'): Service Worker script does not exist at the given path.

Did you forget to run "npx msw init <PUBLIC_DIR>"?

Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/init'

I have tried tweaking options within worker.start(), including changing the url and scope, and using findWorker, which never seemed to execute.

Expected behavior

I expect the service worker to intercept the request.

bug reproduction browser

Most helpful comment

In my monorepo project, karma and its plugins were all hoisted to the root node_modules. It's not always clear to me why yarn chooses to hoist some modules but not others. You could add a nohoist entry to your package.json.

"workspaces": {
  "packages": [
    "examples/*"
  ],
  "nohoist": [
    "**/karma*"
  ]
}

All 15 comments

Hey, @jeffrose. Can you please submit your usage scenario in a repository? I'm having troubles configuring Karma locally and your running project would be of great help to debug this issue. Thanks.

@kettanaito Currently it's part of a larger project that I cannot share, but I'll break it out into a smaller repo.

@kettanaito Here is test project that illustrates the issue.

https://github.com/jeffrose/karma-msw-test

Hi,

For Karrma, the added files are available under the base path.
To make this work with MSW, either change the MSW config or create a proxy

See the opened Pull Request with the changes to make the test pass.

Karma docs: http://karma-runner.github.io/5.2/config/files.html

@jeffrose thank you for preparing that repo!

However, when I try to replicate it I get the following exception from Karma:

10 11 2020 14:34:28.438:ERROR [preprocess]: Can not load "webpack", it is not registered!
  Perhaps you are missing some plugin?

You can see my setup here.

Is there something else I need to install?

@kettanaito Running npm install and npm test should be enough. That error does imply that the karma-webpack plugin isn't available for some reason.

Having said that, @timdeschryver's changes seem to resolve the issue. That should likely go into MSW Recipes, or FAQ.

Yes, I'd love for the entire working repository to go under our Examples repo for the others to reference. @jeffrose may I please ask you for some help with this pull request?

@kettanaito Sure, I will take a look

@kettanaito Karma should implicitly find installed plugins but I think that's failing for some reason in the CI environment. I updated my project to explicitly list the plugins being used.

https://github.com/jeffrose/karma-msw-test/blob/main/karma.conf.cjs#L13

// list of plugins
plugins: [
  'karma-chai',
  'karma-chrome-launcher',
  'karma-mocha',
  'karma-mocha-reporter',
  'karma-webpack'
],

Trying adding that to the karma.conf and see if that resolves the problem.

When I list the plugins explicitly it complains on inability to find the karma-webpack plugin, although it's clearly installed. I suspect this has something to do with running Karma in a monorepo. I've tried setting basePath: __dirname in my karma.conf.cjs, but to no use.

@kettanaito I've run Karma in a monorepo before. I ended up using path to set basePath. I will dig up the configuration and share it with you.

@kettanaito I don't know if it will make a difference or not, but you could try setting the basePath to path.resolve('.'). That's what I did my monorepo project; however my karma.conf was shared across packages whereas yours is contained within a single package.

Is Karma being run from within the package or at the project root? That likely has an impact as well.

I don't think that that's the problem, but that the location of where the npm packages are installed is.
Inside the node modules of the with-karma example, I can see karma-webpack and webpack while karma itself can be found in the root node modules.
If I copy-paste the karma example to it's own repo, it does work...

AFAIK the basePath option is only used to find the spec files.

In my monorepo project, karma and its plugins were all hoisted to the root node_modules. It's not always clear to me why yarn chooses to hoist some modules but not others. You could add a nohoist entry to your package.json.

"workspaces": {
  "packages": [
    "examples/*"
  ],
  "nohoist": [
    "**/karma*"
  ]
}

The nonoist option is what solved the issue. Thank you, @jeffrose!

We now have an official Karma usage example. Please refer to it if you're having troubles setting up Karma and MSW.

Thanks everybody for contribution on this 鉂わ笍

Was this page helpful?
0 / 5 - 0 ratings