Use Jasmine custom matcher with Angular CLI project

851 views Asked by At

I have a simple need: to use my own custom matchers in Jasmine unit tests within an Angular CLI project (Angular v6). A couple constraints:

  • I do not want to modify anything under node_modules; this project has to be able to go through my build pipeline which does a clean install every time.
  • I do not want to have to build an npm module just to be able to add to types in tsconfig.spec.json.

What I have been able to discern so far is that I need a .d.ts file, so this is my matchers.d.ts:

/// <reference path="../../../node_modules/@types/jasmine/index.d.ts" />

declare namespace jasmine {
  interface Matchers<T> {
    toContainPath(path: string): boolean;
  }
}

In the same directory I have my matchers.ts file:

export const customMatchers: jasmine.CustomMatcherFactories  = {

  // Affirms the element contains a sub-element at the given CSS path.
  toContainPath: function (_util, _customEqualityTesters) {
    return {
      compare: function (element: HTMLElement, path: string) {
        const result = {
          pass: false,
          message: ''
        };
        if (!element) {
          result.message = 'Expected element to be non-empty';
        } else if (!path) {
          result.message = 'Expected path to be non-empty';
        } else {
          result.pass = element.querySelector(path) !== null;
          result.message =
            'Expected ' + element + (result.pass ? ' not' : '') + ' to contain ' + path;
        }
        return result;
      }
    };
  }
};

In my test (spec) file, I have:

import { customMatchers } from 'app/testing/matchers';
. . .
/// <reference path="../../../testing/matchers.d.ts" />
. . .
 beforeEach(() => {
    jasmine.addMatchers(customMatchers);
. . .

and finally, I use the matcher in included tests with, e.g.:

expect(element).toContainPath('my-sidebar');

I also tried adding the full path of matchers.d.ts to the types array in tsconfig.spec.json.

Alas, I have not been able to find a solution that works. The failure continues to manifest as error TS2339: Property 'toContainPath' does not exist on type 'Matchers<HTMLElement>'

Promising places I looked, but to no avail:

  1. custom jasmine matchers
  2. adding a jasmine matcher TypeScript definition
  3. jasmine matchers
  4. testing Angular with custom matchers
  5. manually add typing file to TypeScript

Could anyone offer the secret sauce?

1

There are 1 answers

1
tylerthemiler On

The two answers here combined ended up working for me!

Create custom jasmine matcher using Typescript

Added an index.ts to the testing folder and made the .ts and .d.ts files have different names (e.g. custom-matchers.ts and matchers-types.d.ts).