test: Add a test harness for the built card (#2653)

Mounts the card from `dist/` the way Home Assistant does, by URL with a
HACS tag, and asserts the entry stays a facade, that no chunk imports
it, that the browser is served the file unmodified, and that the card
starts up and fetches a language chunk lazily.

Runs in Chromium, Firefox and WebKit, so a change of bundler or minifier
is checked against every engine.
This commit is contained in:
Dermot Duffy
2026-08-03 21:50:21 -07:00
committed by GitHub
parent 18ea725564
commit 2d124fe3cd
18 changed files with 483 additions and 50 deletions
+30 -6
View File
@@ -1,8 +1,8 @@
import { expect, onTestFinished, vi } from 'vitest';
import { ACTION_HANDLER_HOLD_SECONDS } from '../../src/action-handler-directive';
import type { AdvancedCameraCard } from '../../src/card';
import type { RawAdvancedCameraCardConfig } from '../../src/config/types';
import { ACTION_HANDLER_HOLD_SECONDS } from '../../src/const';
import type { FakeEntityOptions, FakeHASS } from './fake-hass';
import { defineHAElementStubs } from './ha-element-stubs';
import { clickElement, deepQuery, deepQueryAll, getAllShadowRoots } from './test-utils';
@@ -400,21 +400,24 @@ export class MountedCard {
/**
* The card is ready to observe but not yet rendered: initializing happens
* after this returns, so a test waits for whatever it will assert on.
*
* `loadCard` puts the card's elements into the page. Where they come from is
* the caller's to decide: `MountedCardFactory` takes them from `src/`, and the
* suite covering a build ("dist") takes them from the file the build
* produced.
*/
public static async create(
loadCard: () => Promise<unknown>,
config: RawAdvancedCameraCardConfig,
hass: FakeHASS,
options?: MountOptions,
): Promise<MountedCard> {
// `src/patches` subclasses Home Assistant's three player elements as soon as
// those are defined, so the stubs must come first.
defineHAElementStubs();
await import('../../src/card');
await loadCard();
return new MountedCard(config, hass, options);
}
private constructor(
protected constructor(
config: RawAdvancedCameraCardConfig,
hass: FakeHASS,
options?: MountOptions,
@@ -613,3 +616,24 @@ export class MountedCard {
this.console.destroy();
}
}
export class MountedCardFactory {
// A card built from `src/`. Constrast with dist.browsers.test.ts .
public static async createFromSource(
config: RawAdvancedCameraCardConfig,
hass: FakeHASS,
options?: MountOptions,
): Promise<MountedCard> {
return await MountedCard.create(
async () => {
// `src/patches` subclasses Home Assistant's three player elements as
// soon as those are defined, so the stubs must come first.
defineHAElementStubs();
await import('../../src/card');
},
config,
hass,
options,
);
}
}