Global propery in JSDOM not being set in integration test (angular-testing-library)

Discussão em 'Angular' iniciado por Florestan Korp, Fevereiro 18, 2025.

  1. I'm not able to set up my testing-library integration tests so they recognize the global interface with the third party static methods from my component library Preline UI

    I'm using JSDOM and angular-testing-library, but I don't know how I can get autoInit() to fire and keep getting an error that the test cannot find HSStaticMethods, which means the internal functionality is not being loaded and I can not test if their components actually integrate with my app!

    declare global {
    interface Window {
    HSStaticMethods: IStaticMethods;
    }
    }

    @Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    selector: 'app-component',
    templateUrl: './app.component.html',
    standalone: true,
    })
    export class AppComponent implements OnInit {
    private readonly router = inject(Router);

    public ngOnInit(): void {
    this.router.events.subscribe((event: Event) => {
    if (event instanceof NavigationEnd) {
    setTimeout(() => {
    // https://www.preline.co/docs/frameworks-angular.html
    window.HSStaticMethods.autoInit();
    }, 100);
    }
    });
    }


    I've tried

    • adding declare global to test-setup.ts and the test itself
    • adding the following to jest.config.ts:

    export default {
    moduleNameMapper: {
    preline: 'node_modules/preline/dist/preline.js', // added this
    }
    }


    My tsconfig.spec.json:

    {
    "extends": "./tsconfig.json",
    "compilerOptions": {
    "outDir": "../../../../dist/out-tsc",
    "module": "commonjs",
    "types": ["jest", "node", "@testing-library/jest-dom", "preline"] // added the lib just in case?
    },
    "files": ["src/test-setup.ts"],
    "include": [
    "jest.config.ts",
    "src/**/*.test.ts",
    "src/**/*.spec.ts",
    "src/**/*.d.ts"
    ]
    }


    And here's the actual integration test:

    import { signal } from '@angular/core';
    import type { RouterEvent } from '@angular/router';
    import { NavigationEnd, Router } from '@angular/router';
    import type { IUser } from '@front-and-workspace/projects/grip-clone';
    import { render } from '@testing-library/angular';
    import { screen } from '@testing-library/dom';
    import userEvent from '@testing-library/user-event';
    import type { IStaticMethods } from 'preline';
    import { BehaviorSubject } from 'rxjs';
    import { AppComponent } from './app.component';
    import { AuthService } from './auth/auth.service';

    // I got desperate and started adding this everywhere :(
    declare global {
    interface Window {
    // eslint-disable-next-line @typescript-eslint/naming-convention
    HSStaticMethods: IStaticMethods;
    }
    }

    jest.useFakeTimers(); // Jest timer so I can control when the setTimeout goes off

    it('should open the Preline dropdown', async () => {
    const user = userEvent.setup();
    const mockEvents$ = new BehaviorSubject<null | RouterEvent>(null);
    const { fixture } = await render(AppComponent, {
    providers: [
    {
    provide: Router,
    useValue: {
    events: mockEvents$,
    routerState: { root: '' },
    createUrlTree: jest.fn(),
    serializeUrl: jest.fn().mockReturnValue(''),
    },
    },
    ],
    });

    mockEvents$.next(new NavigationEnd(0, '', ''));
    jest.runAllTimers(); // ERROR: TypeError: Cannot read properties of undefined (reading 'autoInit')

    let themeToggleDropdownContainer = screen.getByTestId(
    'front-and-workspace-theme-toggle-dropdown-container',
    );

    expect(themeToggleDropdownContainer.className).toBe('hs-dropdown');

    await user.click(
    screen.getByTestId('front-and-workspace-theme-toggle-button'),
    );

    themeToggleDropdownContainer = screen.getByTestId(
    'front-and-workspace-theme-toggle-dropdown-container',
    );

    fixture.detectChanges();

    //Check if drop-down was opened
    expect(themeToggleDropdownContainer.className).toBe('hs-dropdown open');
    });

    Continue reading...

Compartilhe esta Página