Karma keeps showing up as empty coverage

I've been struggling to get karma coverage to work for the past couple of days, but all I keep seeing is a blank empty page like this: https://i.sstatic.net/3Fr6I.png

Check out my configuration:

var path = require('path');

var webpackConfig = require('./webpack.common');

module.exports = function (config) {
  var _config = {
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      { pattern: './karma-shim.js', watched: false }
    ],
    exclude: [],
    preprocessors: {
      './karma-shim.js': ['webpack', 'sourcemap', 'coverage']
    },
    client: {
      captureConsole: false
    },
    webpack: webpackConfig,

    webpackMiddleware: {
      stats: 'errors-only'
    },

    coverageReporter: {
      dir: 'coverage/',
      reporters: [{
        type: 'json',
        dir: 'coverage',
        subdir: 'json',
        file: 'coverage-final.json'
      }]
    },

    remapIstanbulReporter: {
      src: 'coverage/json/coverage-final.json',
      reports: {
        lcovonly: 'coverage/json/lcov.info',
        html: 'coverage/html',
        'text': null
      },
      timeoutNotCreated: 1000, // default value
      timeoutNoMoreFiles: 1000 // default value
    },

    webpackServer: {
      noInfo: true // please don't spam the console when running in karma!
    },
    reporters: ["mocha", "coverage", "karma-remap-istanbul"],
    port: 9876,
    colors: true,
    logLevel: config.LOG_ERROR,
    autoWatch: false,
    browsers: ['PhantomJS'], // you can also use Chrome

    singleRun: true
  };

  config.set(_config);

};

Here's the content of my karma-shim.js file:

Error.stackTraceLimit = Infinity;
require('es6-shim');
require('reflect-metadata');
require('ts-helpers');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');

var appContext = require.context('./app', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);

var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');

testing.setBaseTestProviders(browser.TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, browser.TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);

This is how my folder structure looks: https://i.sstatic.net/1Eb2s.png

If you have any insights on what might be causing this issue, your help would be greatly appreciated.

Thank you!

Answer №1

Your current karma setup is indicating a lack of source reference.

To rectify this issue, please update your configuration as outlined below:

module.exports = function (config) {
    var _config = {
        [...]
        preprocessors: {
            // Ensure coverage is not applied as a preprocessor for your tests - 
            // Karma's Istanbul will handle instrumentation behind the scenes
            './karma-shim.js': ['webpack', 'sourcemap'],
            // Include the path to your source files (.js or .ts depending on your project)
            './index.ts': [ 'coverage' ]
        },
        [...]
    },
    [...]
}

Explanation: Code coverage evaluates your code against unit tests - providing an entry point in your config enables Karma to analyze coverage.

Additional - integration of karma-coverage plugin:

module.exports = function (config) {
    var _config = {
        [...]
        plugins: [
            require( 'karma-coverage' )
        ],
        [...]
    },
    [...]
}

Extra tip - incorporating karma and typescript files:

module.exports = function (config) {
    var _config = {
        [...]
        plugins: [
            require( '@angular/cli/plugins/karma' )
        ],
        [...]
    },
    [...]
    preprocessors: {
        './src/test.ts': [ '@angular/cli' ],
        './index.ts': [ 'coverage' ]
    },
    [...]
    mime: {
       'text/x-typescript': [ 'ts', 'tsx' ]
    },
    [...]
}

Answer №2

Make sure to include the --code-coverage flag when executing the test. This simple addition resolved an issue I was facing. Here's an example:

ng test --watch=false --code-coverage

Answer №3

I encountered the same issue and after exhausting all online resources without success, I devised a challenging yet surprisingly simple solution:

  1. Begin by either creating a new folder or completely clearing out the contents of your project's existing folder (IF YOU DECIDE TO DELETE THE CONTENT, ENSURE YOU ADD, COMMIT, AND PUSH EVERYTHING FIRST), then proceed to clone the project afresh.

  2. Next, execute the command "npm install" as usual.

  3. Copy the code snippet below and use it to replace the content in your karma.conf.js file:

     // Karma configuration
    module.exports = function (config) {
       config.set({
         basePath: '',
         frameworks: ['jasmine', '@angular-devkit/build-angular'],
         plugins: [
           require('karma-jasmine'),
           require('karma-chrome-launcher'),
           require('karma-jasmine-html-reporter'),
           require('karma-coverage-istanbul-reporter'),
           require('@angular-devkit/build-angular/plugins/karma')
         ],
         client: {
           clearContext: false // leave Jasmine Spec Runner output visible in browser
         },
         coverageIstanbulReporter: {
           dir: require('path').join(__dirname, 'coverage'),
           reports: ['html', 'lcovonly', 'text-summary'],
           fixWebpackSourcePaths: true
         },
         reporters: ['progress', 'kjhtml'],
         port: 9876,
         colors: true,
         logLevel: config.LOG_INFO,
         autoWatch: true,
         browsers: ['Chrome'],
         singleRun: false,
         restartOnFileChange: false,
       });
    };
    

The culprit behind the issue most likely lies within the 'coverage' section mentioned here:

    dir: require('path').join(__dirname, 'coverage'), 

In my scenario, the initial setup looked like this:

    dir: require('path').join(__dirname, './../coverage/360-app'),

This caused considerable headaches for me. Rectifying this mistake can be tricky once established incorrectly from the start.

Following the re-clone, I was able to achieve the desired outcome: https://i.sstatic.net/kcUGB.png

Wishing everyone facing similar challenges the best of luck.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The relationship between Vue TypeScript props is influenced by the presence of another prop

Is there a way to define a property in <script setup lang="ts"> that depends on another property? For instance, how can I require a variable only if another variable is present? I attempted using defineProps<Props | PropsA>(), but e ...

Exploring the weather API integration with Angular 4

I've embarked on a journey to teach myself Angular4 by creating a Weather app. However, I'm facing challenges in connecting the API. Despite consulting various resources, such as: https://medium.com/craft-academy/connecting-an-api-to-an-angular- ...

Unsupported method 'keys' for the specified object - (Internet Explorer 11)

I'm having trouble identifying the issue in Internet Explorer 11. The application functions perfectly without any problems in other browsers such as Chrome and Firefox. https://i.stack.imgur.com/5QvML.png ...

Steps to resolve the issue with "Error: StaticInjectorError(AppModule)[NgbDropdown -> ChangeDetectorRef]"

My attempt at creating a web app using Angular resulted in successful compilation with no errors. However, upon execution, the browser displays a blank page accompanied by the following error message: ERROR Error: Uncaught(in promise): Error: St ...

Exploring the concept of using a single route with multiple DTOs in NestJS

At the moment, I am utilizing NestJS for creating a restful API. However, I am currently facing an issue with the ValidationPipe. It seems to only be functioning properly within controller methods and not when used in service methods. My goal is to implem ...

What is the best way to merge multiple *ngifs in Angular?

Hey there, I am looking to create a conditional statement with three different outputs that will be displayed in a table. Currently, this is the code snippet I have: <td><div *ngIf="todo.diffDays >90">ninety</div> </td> I want ...

What led Google to create Puppeteer despite the availability of Protractor?

What was Google's reasoning behind the decision to create Puppeteer, despite the existence of Protractor, especially for Angular? ...

Error message: "Property 'item' is not found within type 'P' - The property is inaccessible in the higher order component even though it is included in the props."

I am currently learning about typescript and exploring how to use Higher Order Components (HoCs) with React in a specific scenario. In my case, I am trying to wrap a component with an HoC that checks whether the "item" passed into the "wrapped" component ...

Is there a way to receive messages from background.js of a Chrome Extension within an Angular web application?

I've developed a Chrome Extension that sends messages to all tabs (through background.js) using the following code: chrome.tabs.query({}).then((tabs)=> { if (tabs) { tabs.forEach(tab => { chrome.tabs.sendM ...

Tips for creating a "sticky" button in Angular that reveals a menu when clicked

Is there a way to incorporate a feature similar to the "Get help" button on this website: The button, located in the lower right corner, opens a sticky chat menu. I am interested in adding dynamic information to the button (such as the number of tasks a u ...

Creating AgGrid as a part of a flexible component instantiation

I am looking to integrate Ag-grid into a dynamic component within Angular. I am encountering issues with the format when the host calls componentFactoryResolver on the component containing the agGrid instance. I would appreciate any guidance on how to prop ...

Harness the power of moment.js in webpack 4 by integrating it with ts-loader

I'm facing an issue where moment.js isn't loading inside a TypeScript file during the webpack4 build process, no matter what I attempt. [tsl] ERROR in /app/Repository/JFFH.Site/Resources/Private/JavaScript/Angular/schedule/schedule.component.ts( ...

Tips for efficiently combining mergeMap observables and providing a singular value for the entire observable

Consider this particular case involving TypeScript/angular with rxjs 6.5: main(){ const items = ['session', 'user']; const source: Observable<any> = from(items); source .pipe( ...

What is the best way to adjust the height of a dropdown box in an angular application?

Is there a way to change the height of the scroll view? It seems too long for my liking, any advice? I attempted to adjust it using css but unfortunately, it didn't work out. The scroll view appears excessively lengthy as shown in the image below. h ...

Can you provide some instances where Angular2 ag-grid pagination has been implemented?

Are there any examples of how to use ag-grid pagination with Angular2, particularly when it comes to virtual paging or infinite scrolling? I've been searching for a while but haven't found anything helpful. Any assistance would be greatly appreci ...

CSS that relies on the presence of a specific class

I'm a CSS novice and I have encountered a scenario where I need to apply a CSS class only when another class is not present. <div class="border-solid p-2 bg-white mt-1 h-fit" [ngClass]="SOME_CONDITION ? 'tile-con ...

Child stateless component in React receiving outdated props from parent Class component

Within my Parent Component, there is a form that users interact with. The form displays real-time information that updates as fields are edited. However, I am encountering an issue where the child component sometimes receives outdated props from the previo ...

What is the best way to choose multiple checkboxes by clicking a single checkbox labeled "Select All"?

I am currently developing with angular 4 and have a requirement to select all services (checkbox) when the "All" checkbox is checked. component.ts industries : any = [ { "industry_name" : "Lawn Care", "value" : "lawn_care", "service_cat ...

What is the process for setting up a subrouter using React Router v6?

This is the current React Router setup I am using: const router = createBrowserRouter([ { path: "/", element: ( <Page activeNav="home" > <Home /> </Page> ) }, { ...

The Angular and Node.js console reports an error message reading, "Unauthorized: GET http://localhost:4200/user/profile."

I've been facing an issue while attempting to save data into /profile post login. The console is showing me these two errors after logging in: "VM276:1 GET http://localhost:4200/user/profile 401 (Unauthorized)" "HttpErrorResponse {hea ...