diff --git a/projects/ngx-speculoos/src/lib/matchers.spec.ts b/projects/ngx-speculoos/src/lib/matchers.spec.ts
new file mode 100644
index 00000000..3147c11e
--- /dev/null
+++ b/projects/ngx-speculoos/src/lib/matchers.spec.ts
@@ -0,0 +1,67 @@
+import { Component } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ComponentTester } from './component-tester';
+import { elementMatchers } from './matchers';
+
+@Component({
+ template: `
+
Hello
+ Hello
+ `
+})
+class TestComponent {
+}
+
+class TestComponentTester extends ComponentTester {
+ constructor() {
+ super(TestComponent);
+ }
+
+ get div() {
+ return this.element('#classes');
+ }
+
+ get none() {
+ return this.element('#none');
+ }
+}
+
+describe('Custom matchers', () => {
+
+ let tester: TestComponentTester;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({ declarations: [TestComponent] });
+ tester = new TestComponentTester();
+ tester.detectChanges();
+ jasmine.addMatchers(elementMatchers);
+ });
+
+ it('should check for a class', () => {
+ expect(tester.div).toHaveClass('foo');
+ expect(tester.div).not.toHaveClass('baz');
+
+ const matcher = elementMatchers.toHaveClass(undefined, undefined);
+
+ // missing class
+ let result = matcher.compare(tester.div, 'baz');
+ expect(result.pass).toBeFalsy();
+ expect(result.message).toBe(`Expected element to have class 'baz', but had 'foo, bar'`);
+
+ // no class
+ result = matcher.compare(tester.none, 'baz');
+ expect(result.pass).toBeFalsy();
+ expect(result.message).toBe(`Expected element to have class 'baz', but had none`);
+
+ // null element
+ result = matcher.compare(null, 'baz');
+ expect(result.pass).toBeFalsy();
+ expect(result.message).toBe(`Expected element to have class 'baz', but element was falsy`);
+
+ // not a TestElement
+ result = matcher.compare('hello', 'baz');
+ expect(result.pass).toBeFalsy();
+ expect(result.message).toBe(`Expected element to have class 'baz', but element was not a TestElement`);
+ });
+});
diff --git a/projects/ngx-speculoos/src/lib/matchers.ts b/projects/ngx-speculoos/src/lib/matchers.ts
new file mode 100644
index 00000000..f6baad60
--- /dev/null
+++ b/projects/ngx-speculoos/src/lib/matchers.ts
@@ -0,0 +1,25 @@
+import { TestElement } from './test-element';
+const elementMatchers: jasmine.CustomMatcherFactories = {
+
+ /**
+ * Checks that an element has the specified class
+ */
+ toHaveClass: (util: jasmine.MatchersUtil, customEqualityTesters: Array): jasmine.CustomMatcher => {
+ return {
+ compare: (el: any, expected: string): jasmine.CustomMatcherResult => {
+ if (!el) {
+ return { pass: false, message: `Expected element to have class '${expected}', but element was falsy` };
+ }
+ if (!(el instanceof TestElement)) {
+ return { pass: false, message: `Expected element to have class '${expected}', but element was not a TestElement` };
+ }
+ const actual = el.classes;
+ const pass = actual.includes(expected);
+ const message = `Expected element to have class '${expected}', but had ${actual.length ? '\'' + actual.join(', ') + '\'' : 'none'}`;
+ return { pass, message };
+ }
+ };
+ }
+};
+
+export { elementMatchers };
diff --git a/projects/ngx-speculoos/src/matchers-types.d.ts b/projects/ngx-speculoos/src/matchers-types.d.ts
new file mode 100644
index 00000000..ecc1a626
--- /dev/null
+++ b/projects/ngx-speculoos/src/matchers-types.d.ts
@@ -0,0 +1,5 @@
+declare namespace jasmine {
+ interface Matchers {
+ toHaveClass(className: string): boolean;
+ }
+}
diff --git a/projects/ngx-speculoos/src/public_api.ts b/projects/ngx-speculoos/src/public_api.ts
index f1f56d98..009425bf 100644
--- a/projects/ngx-speculoos/src/public_api.ts
+++ b/projects/ngx-speculoos/src/public_api.ts
@@ -1,6 +1,7 @@
/*
* Public API Surface of ngx-speculoos
*/
+///
export * from './lib/component-tester';
export * from './lib/test-element';
@@ -9,3 +10,4 @@ export * from './lib/test-input';
export * from './lib/test-button';
export * from './lib/test-select';
export * from './lib/route';
+export * from './lib/matchers';
diff --git a/projects/ngx-speculoos/tsconfig.lib.json b/projects/ngx-speculoos/tsconfig.lib.json
index 19338590..9f4f6dc1 100644
--- a/projects/ngx-speculoos/tsconfig.lib.json
+++ b/projects/ngx-speculoos/tsconfig.lib.json
@@ -12,7 +12,9 @@
"experimentalDecorators": true,
"importHelpers": true,
"strict": true,
- "types": [],
+ "types": [
+ "@types/jasmine"
+ ],
"lib": [
"dom",
"es2015"