Skip to content

[Bug]: Custom DOM matchers not re-exported or wired into expect() #8

Description

@MelGidsen

Checklist

  • I have searched the existing issues and have not found a duplicate
  • I have read the README and documentation and have not found a solution
  • I agree to follow the OpenNG Foundation Code of Conduct

What happened?

The custom DOM matchers documented in the README (toHaveText, toHaveAttribute, toExist, toHaveClass, toBeHidden, etc.) are meant to be usable directly on expect(...) after importing from @openng/spectator/vitest or @openng/spectator/jest, without any manual expect.extend() call. This is wired up via an ambient type declaration file that augments Vitest's Assertion interface (or Jest's Matchers interface).

The compiled JS bundles still contain a reference to this file:

/// <reference types="vitest" />
/// <reference path="./lib/matchers-types.ts" preserve="true" />

(present in fesm2022/openng-spectator-vitest.mjs, fesm2022/openng-spectator-jest.mjs, and the root fesm2022/openng-spectator.mjs)

However, the corresponding matchers-types.d.ts file is not included anywhere in the published package, and none of the shipped .d.ts entry points (types/openng-spectator.d.ts, types/openng-spectator-vitest.d.ts, types/openng-spectator-jest.d.ts, types/openng-spectator-internals.d.ts) carry a /// <reference path="./lib/matchers-types.ts" /> directive of their own.

The ambient interface augmentation for Assertion<T> / Matchers<R> never happens, so TypeScript has no declaration for these matchers even though the underlying functions are fully implemented and exported at runtime.

Steps to reproduce

  1. Setup spectator with vitest per documentation
  2. Create a spec and try to use any DOM Matcher like this:
import { createPipeFactory, SpectatorPipe } from '@openng/spectator/vitest';
import { MyPipe } from './my.pipe';

describe('MyPipe', () => {
  const createPipe = createPipeFactory(MyPipe);

  it('renders text', () => {
    const spectator = createPipe(`{{ 'test' | myPipe }}`);
    expect(spectator.element).toHaveText('test');
    // TS2339: Property 'toHaveText' does not exist on type 'Assertion<Element>'.
  });
});
  1. Observe compile error

Expected behavior

expect(element).toHaveText(...), expect(element).toHaveAttribute(...), expect(element).toExist(), and the other documented custom matchers should type-check without errors when importing from @openng/spectator/vitest or @openng/spectator/jest, matching the behavior documented in the README.

Actual behavior

TS2339: Property 'toHaveText' does not exist on type 'Assertion<Element>'.

...and the equivalent error for every other custom matcher listed in the README (confirmed with toHaveAttribute and toExist as well), even though the underlying matcher functions are still exported and the JS bundle still references the (missing) type augmentation file.

Minimal reproduction

https://github.com/MelGidsen/spectator-missing-declaration

Library version

1.0.0

Angular version

22.0.6

Node version

24.18.0

Package manager

npm

Browser(s)

Chrome

Environment details

- Test runner: Vitest (also affects the `/jest` entry point based on the same missing reference)

Angular application setup

Standalone components

Angular context

  • SSR (Server-Side Rendering) is involved
  • Zoneless change detection is enabled

Relevant log output

X [ERROR] TS2339: Property 'toHaveText' does not exist on type 'Assertion<Element>'. [plugin angular-compiler]

    src/app/to-string.pipe.spec.ts:12:30:
      12 │     expect(spectator.element).toHaveText('test');

Screenshots

No response

Additional context

Locally re-declaring the missing ambient interface augmentation as a workaround:

declare module 'vitest' {
  interface Assertion<T = unknown> {
    toHaveText(expected: string): void;
    toHaveAttribute(attr: string, value?: string): void;
   // ...
  }
}

...immediately resolves the TS2339 errors for all affected call sites, confirming this is purely a missing declaration file issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions