Testing events with RequireJs + Karma + Jasmine

i’m trying to find a way to test events. Like in topic title my stack is RequireJs + Karma + Jasmine. I dont want to use jQuery or any not essential external libraries.

There’s icon-utils code i use in my navbar:
icon -utils.js

define('icon-utils', [], function () {
  return {
    toggleIcon: function (icon, baseIcon, toggledIcon) {
      if (baseIcon === icon.getAttribute("data-icon")) {
        icon.setAttribute("data-icon", toggledIcon);
      } else {
        icon.setAttribute("data-icon", baseIcon);
      }
    }
  };
});

And test of it:

define(['icon-utils'], function(iconUtils) {
  describe('test iconUtils', function () {
    let toggledIcon = 'toggledIcon';
    let baseIcon = 'unToggledIcon';

    it('should change icon to toggled', function() {
      let icon = document.createElement("i");
      icon.setAttribute("data-icon", baseIcon)

      iconUtils.toggleIcon(icon, baseIcon, toggledIcon);
      expect(icon.getAttribute("data-icon")).toEqual(toggledIcon)
    });

    it('should change icon to unToggled', function() {
      let icon = document.createElement("i");
      icon.setAttribute("data-icon", toggledIcon)

      iconUtils.toggleIcon(icon, baseIcon, toggledIcon);
      expect(icon.getAttribute("data-icon")).toEqual(baseIcon)
    });
  })
})

Now there is my nabar.js i want to test

define('navbar', ['icon-utils'], function (iconUtils) {
  Array.from(document.getElementsByClassName("jb-navbar-menu-toggle")).forEach(
    (el) => {
      el.addEventListener("click", (e) => {
        console.log("clicked");
        const dropdownIcon = e.currentTarget
          .getElementsByClassName("icon")[0]
          .getElementsByClassName("material-icons")[0];

        document
          .getElementById(e.currentTarget.getAttribute("data-target"))
          .classList.toggle("is-active");

        iconUtils.toggleIcon(dropdownIcon, "more_vert", "close");
      });
    }
  );
});

And yeah i need to test if class of selected dom element is changing on click:

define(['navbar'], function(navBar) {
  describe('test navBar', function () {
    
      it('should toggle is-active class on click ', function() {
      });
    })
})

I spent a lot of time looking for good solution, but i couldn’t find anything helpful. I need to find a way to attach event listener from navbar.js to dom element and check if event was triggered and if is-active class was toggled.

Also as there is not much good sources of testing pure Js i would appreciate every tips that will help me keep good practices and write quality tests.

There is also my karma.conf.js if it is any helpful:

// Karma configuration
// Generated on Tue Feb 09 2021 08:09:01 GMT+0100 (Central European Standard Time)

module.exports = function (config) {
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '../..',


    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'requirejs'],


    // list of files / patterns to load in the browser
    files: [
      'tests/Ecommerce.Admin.Tests/test-main.js',
      {pattern: 'src/Ecommerce.Admin/wwwroot/js/**/*.js', included: false},
      {pattern: 'tests/Ecommerce.Admin.Tests/js/**/*.spec.js', included: false},
    ],


    // list of files / patterns to exclude
    exclude: [],


    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {},


    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress'],


    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_DEBUG,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome'],


    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity,

    captureTimeout: 210000,
    browserDisconnectTolerance: 3,
    browserDisconnectTimeout : 210000,
    browserNoActivityTimeout : 210000,
  })
}

20 thoughts on “Testing events with RequireJs + Karma + Jasmine”

Leave a Comment