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
);