Skip to content

Commit dc0c229

Browse files
fix(test): refactor AnimateCSS tests after jsdom 27 upgrade
1 parent f04febf commit dc0c229

File tree

2 files changed

+77
-40
lines changed

2 files changed

+77
-40
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Thanks to: @dathbe.
4545
### Updated
4646

4747
- [calendar] Update defaultSymbol name and also the link to the icon search site (#3879)
48-
- [core] Update dependencies including electron to v38 as well as github actions (#3831, #3849, #3857, #3858, #3872, #3876, #3882)
48+
- [core] Update dependencies including electron to v38 as well as github actions (#3831, #3849, #3857, #3858, #3872, #3876, #3882, #3891)
4949
- [weather] Update feels_like temperature calculation formula (#3869)
5050

5151
### Fixed
@@ -56,6 +56,7 @@ Thanks to: @dathbe.
5656
- [calendar] Fix regression handling of limit days (#3840)
5757
- [calendar] Fixed regression of calendarfetcherutils.shouldEventBeExcluded (#3841)
5858
- [core] Fixed socket.io timeout when server is slow to send notification, notification lost at client (#3380)
59+
- [tests] refactor AnimateCSS tests after jsdom 27 upgrade (#3891)
5960
- [weather] Use `apparent_temperature` data from openmeteo's hourly weather for current feelsLikeTemp (#3868).
6061

6162
## [2.32.0] - 2025-07-01

tests/e2e/animateCSS_spec.js

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,109 @@
11
const helpers = require("./helpers/global-setup");
22

3+
// Validate Animate.css integration for compliments module using class toggling.
4+
// We intentionally ignore computed animation styles (jsdom doesn't simulate real animations).
35
describe("AnimateCSS integration Test", () => {
4-
// define config file for testing
5-
let testConfigFile = "tests/configs/modules/compliments/compliments_animateCSS.js";
6-
// define config file to fallback to default: wrong animation name (must return no animation)
7-
let testConfigFileFallbackToDefault = "tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js";
8-
// define config file with an inverted name animation : in for out and vice versa (must return no animation)
9-
let testConfigFileInvertedAnimationName = "tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js";
10-
// define config file with no animation defined
11-
let testConfigByDefault = "tests/configs/modules/compliments/compliments_anytime.js";
6+
// Config variants under test
7+
const TEST_CONFIG_ANIM = "tests/configs/modules/compliments/compliments_animateCSS.js";
8+
const TEST_CONFIG_FALLBACK = "tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js"; // invalid animation names
9+
const TEST_CONFIG_INVERTED = "tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js"; // in/out swapped
10+
const TEST_CONFIG_NONE = "tests/configs/modules/compliments/compliments_anytime.js"; // no animations defined
1211

1312
/**
14-
* move similar tests in function doTest
15-
* @param {string} [animationIn] animation in name of AnimateCSS to test.
16-
* @param {string} [animationOut] animation out name of AnimateCSS to test.
17-
* @returns {boolean} result
13+
* Get the compliments container element (waits until available).
14+
* @returns {Promise<HTMLElement>} compliments root element
1815
*/
19-
const doTest = async (animationIn, animationOut) => {
16+
async function getComplimentsElement () {
2017
await helpers.getDocument();
21-
let elem = await helpers.waitForElement(".compliments");
22-
expect(elem).not.toBeNull();
23-
let styles = window.getComputedStyle(elem);
18+
const el = await helpers.waitForElement(".compliments");
19+
expect(el).not.toBeNull();
20+
return el;
21+
}
2422

25-
if (animationIn && animationIn !== "") {
26-
expect(styles._values.get("animation-name")).toBe(animationIn);
27-
} else {
28-
expect(styles._values.get("animation-name")).toBeUndefined();
23+
/**
24+
* Wait for an Animate.css class to appear and persist briefly.
25+
* @param {string} cls Animation class name without leading dot (e.g. animate__flipInX)
26+
* @param {{timeout?: number}} [options] Poll timeout in ms (default 6000)
27+
* @returns {Promise<boolean>} true if class detected in time
28+
*/
29+
async function waitForAnimationClass (cls, { timeout = 6000 } = {}) {
30+
const start = Date.now();
31+
while (Date.now() - start < timeout) {
32+
if (document.querySelector(`.compliments.animate__animated.${cls}`)) {
33+
// small stability wait
34+
await new Promise((r) => setTimeout(r, 50));
35+
if (document.querySelector(`.compliments.animate__animated.${cls}`)) return true;
36+
}
37+
await new Promise((r) => setTimeout(r, 100));
2938
}
39+
throw new Error(`Timeout waiting for class ${cls}`);
40+
}
3041

31-
if (animationOut && animationOut !== "") {
32-
elem = await helpers.waitForElement(`.compliments.animate__animated.animate__${animationOut}`);
33-
expect(elem).not.toBeNull();
34-
styles = window.getComputedStyle(elem);
35-
expect(styles._values.get("animation-name")).toBe(animationOut);
36-
} else {
37-
expect(styles._values.get("animation-name")).toBeUndefined();
42+
/**
43+
* Assert that no Animate.css animation class is applied within a time window.
44+
* @param {number} [ms] Observation period in ms (default 2000)
45+
* @returns {Promise<void>}
46+
*/
47+
async function assertNoAnimationWithin (ms = 2000) {
48+
const start = Date.now();
49+
while (Date.now() - start < ms) {
50+
if (document.querySelector(".compliments.animate__animated")) {
51+
throw new Error("Unexpected animate__animated class present in non-animation scenario");
52+
}
53+
await new Promise((r) => setTimeout(r, 100));
54+
}
55+
}
56+
57+
/**
58+
* Run one animation test scenario.
59+
* @param {string} [animationIn] Expected animate-in name
60+
* @param {string} [animationOut] Expected animate-out name
61+
* @returns {Promise<boolean>} true when scenario assertions pass
62+
*/
63+
async function runAnimationTest (animationIn, animationOut) {
64+
await getComplimentsElement();
65+
if (!animationIn && !animationOut) {
66+
await assertNoAnimationWithin(2000);
67+
return true;
68+
}
69+
if (animationIn) await waitForAnimationClass(`animate__${animationIn}`);
70+
if (animationOut) {
71+
// Wait just beyond one update cycle (updateInterval=2000ms) before expecting animateOut.
72+
await new Promise((r) => setTimeout(r, 2100));
73+
await waitForAnimationClass(`animate__${animationOut}`);
3874
}
3975
return true;
40-
};
76+
}
4177

4278
afterEach(async () => {
4379
await helpers.stopApplication();
4480
});
4581

4682
describe("animateIn and animateOut Test", () => {
4783
it("with flipInX and flipOutX animation", async () => {
48-
await helpers.startApplication(testConfigFile);
49-
await expect(doTest("flipInX", "flipOutX")).resolves.toBe(true);
84+
await helpers.startApplication(TEST_CONFIG_ANIM);
85+
await expect(runAnimationTest("flipInX", "flipOutX")).resolves.toBe(true);
5086
});
5187
});
5288

5389
describe("use animateOut name for animateIn (vice versa) Test", () => {
54-
it("without animation", async () => {
55-
await helpers.startApplication(testConfigFileInvertedAnimationName);
56-
await expect(doTest()).resolves.toBe(true);
90+
it("without animation (inverted names)", async () => {
91+
await helpers.startApplication(TEST_CONFIG_INVERTED);
92+
await expect(runAnimationTest()).resolves.toBe(true);
5793
});
5894
});
5995

6096
describe("false Animation name test", () => {
61-
it("without animation", async () => {
62-
await helpers.startApplication(testConfigFileFallbackToDefault);
63-
await expect(doTest()).resolves.toBe(true);
97+
it("without animation (invalid names)", async () => {
98+
await helpers.startApplication(TEST_CONFIG_FALLBACK);
99+
await expect(runAnimationTest()).resolves.toBe(true);
64100
});
65101
});
66102

67103
describe("no Animation defined test", () => {
68-
it("without animation", async () => {
69-
await helpers.startApplication(testConfigByDefault);
70-
await expect(doTest()).resolves.toBe(true);
104+
it("without animation (no config)", async () => {
105+
await helpers.startApplication(TEST_CONFIG_NONE);
106+
await expect(runAnimationTest()).resolves.toBe(true);
71107
});
72108
});
73109
});

0 commit comments

Comments
 (0)