Angular
Table of Contents
Testing with Jest#
Jest uses jsdom and supports ShadowDOM since Version 12.2.0. However, it doesn't support JavaScript modules as
described in this issue. Also, it doesn't support
CSSStyleSheet.replace(), Intersection Observer, Element.prototype.scrollTo and others.
As a workaround we provide a polyfill as part of the @porsche-design-system/components-angular package.
To apply the polyfill, simply import it in your setupTest.{js|ts} file.

Certain modern browser APIs are not supported in the jsdom environment. See Unsupported
APIs for more information.
Setup file
import '@porsche-design-system/components-angular/jsdom-polyfill';
Example component
import { ChangeDetectionStrategy, Component } from '@angular/core';
import type { TabsBarUpdateEventDetail } from '@porsche-design-system/components-angular';
@Component({
selector: 'single-component',
template: `
<p-tabs-bar [activeTabIndex]="tabIndex" (update)="onUpdate($event)">
<button data-testid="button1" type="button">Tab One</button>
<button data-testid="button2" type="button">Tab Two</button>
<button data-testid="button3" type="button">Tab Three</button>
</p-tabs-bar>
<div data-testid="debug">Active Tab: { tabIndex + 1 }</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SingleComponent {
tabIndex: number = 0;
onUpdate(e: CustomEvent<TabsBarUpdateEventDetail>) {
this.tabIndex = e.detail.activeTabIndex;
}
}
Test example component
import { componentsReady } from '@porsche-design-system/components-angular';
import { render } from '@testing-library/angular';
import userEvent from '@testing-library/user-event';
import '@porsche-design-system/components-angular/jsdom-polyfill';
it('should render Tabs Bar from Porsche Design System and use its events', async () => {
const { getByTestId } = await render(SingleComponent);
await componentsReady();
const debug = getByTestId('debug');
const button1 = getByTestId('button1');
const button2 = getByTestId('button2');
const button3 = getByTestId('button3');
expect(debug.innerHTML).toBe('Active Tab: 1');
await userEvent.click(button2);
expect(debug.innerHTML).toBe('Active Tab: 2');
await userEvent.click(button3);
expect(debug.innerHTML).toBe('Active Tab: 3');
await userEvent.click(button1);
expect(debug.innerHTML).toBe('Active Tab: 1');
});
More test examples can be found at the componentsReady() documentation.
Unsupported APIs#
Certain modern browser APIs are not supported in the jsdom environment.
Dialog API
Affected Components: p-modal, p-flyout, p-flyout-multilevel
Due to the lack of native support in jsdom, the Dialog API needs to be either manually polyfilled or mocked. You can use
the available dialog-polyfill package or create a custom mock
implementation.
Example mock:
HTMLDialogElement.prototype.show = jest.fn();
HTMLDialogElement.prototype.showModal = jest.fn();
HTMLDialogElement.prototype.close = jest.fn();
Element Internals API
Affected Components: p-textarea
Current polyfills for the Element Internals API are incompatible with Stencil. Therefore, the API must be mocked within
the test setup.
Example mock:
HTMLElement.prototype.attachInternals = jest.fn(
() =>
({
setFormValue: jest.fn(),
setValidity: jest.fn(),
}) as ElementInternals
);