From 88553b93b54f8a12c67207d9c3c479ac03d88368 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 5 Aug 2026 09:51:02 +0100 Subject: [PATCH] Stabilise Vitest MatrixChat test (#34555) * Stabilise Vitest MatrixChat test * Ignore post-teardown exceptions in vitest * Iterate --- .../views/elements/LanguageDropdown.tsx | 10 +++++++++ apps/web/src/test/setupTests.ts | 22 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/views/elements/LanguageDropdown.tsx b/apps/web/src/components/views/elements/LanguageDropdown.tsx index a61bc8281e..5948a49148 100644 --- a/apps/web/src/components/views/elements/LanguageDropdown.tsx +++ b/apps/web/src/components/views/elements/LanguageDropdown.tsx @@ -39,6 +39,8 @@ interface IState { } export default class LanguageDropdown extends React.Component { + private unmounted = false; + public constructor(props: IProps) { super(props); @@ -49,8 +51,11 @@ export default class LanguageDropdown extends React.Component { } public componentDidMount(): void { + this.unmounted = false; + getAllLanguagesWithLabels() .then((langs) => { + if (this.unmounted) return; langs.sort(function (a, b) { if (a.labelInTargetLanguage < b.labelInTargetLanguage) return -1; if (a.labelInTargetLanguage > b.labelInTargetLanguage) return 1; @@ -59,6 +64,7 @@ export default class LanguageDropdown extends React.Component { this.setState({ langs }); }) .catch(() => { + if (this.unmounted) return; this.setState({ langs: [ { @@ -78,6 +84,10 @@ export default class LanguageDropdown extends React.Component { } } + public componentWillUnmount(): void { + this.unmounted = true; + } + private onSearchChange = (search: string): void => { this.setState({ searchQuery: search, diff --git a/apps/web/src/test/setupTests.ts b/apps/web/src/test/setupTests.ts index 6368d6e52b..13f8f64cb0 100644 --- a/apps/web/src/test/setupTests.ts +++ b/apps/web/src/test/setupTests.ts @@ -18,9 +18,26 @@ declare global { globalThis.IS_REACT_ACT_ENVIRONMENT = true; +// Ignore benign post-teardown exceptions as they cause flakes +const guardState = globalThis as unknown as { __vitestTestRunning?: boolean; __teardownGuardInstalled?: boolean }; +if (!guardState.__teardownGuardInstalled) { + guardState.__teardownGuardInstalled = true; + const isPostTeardownStraggler = (): boolean => !guardState.__vitestTestRunning || typeof window === "undefined"; + process.on("uncaughtException", (err) => { + if (isPostTeardownStraggler()) return; + throw err; + }); + process.on("unhandledRejection", (reason) => { + if (isPostTeardownStraggler()) return; + throw reason; + }); +} + manageFetchMockGlobally(); beforeEach(() => { + guardState.__vitestTestRunning = true; + vi.stubEnv("TZ", "UTC"); // set up fetch API mock @@ -31,7 +48,10 @@ beforeEach(() => { setupLanguageMock(); }); -afterEach(() => fetchMock.callHistory.flush()); +afterEach(() => { + guardState.__vitestTestRunning = false; + return fetchMock.callHistory.flush(); +}); // uninitialised SdkConfig causes lots of warnings in console, init with defaults SdkConfig.put(DEFAULTS);