test(ui): flush passive effects with React act in CompanySkills tests
The local act helper wrapped flushSync, which flushes render work but not passive effects. The install dialog seeds its state in a useEffect, so tests added a setTimeout(0) hop to give it a chance to run. A setTimeout callback and React's own scheduler task queue in a different order each run, so the hop sometimes lost the race and the test read stale state. Delegate the helper to React's own act, which flushes passive effects before it resolves, and remove the now-unneeded timing hops. Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
a7ed22e3dd
commit
834f33c31b
|
|
@ -1,7 +1,6 @@
|
|||
// @vitest-environment jsdom
|
||||
|
||||
import type { ComponentProps, ReactNode } from "react";
|
||||
import { flushSync } from "react-dom";
|
||||
import { act as reactAct, type ComponentProps, type ReactNode } from "react";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
import type { CatalogSkill, CompanySkillDetail, CompanySkillListItem, CompanySkillVersion, FolderListResult } from "@paperclipai/shared";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
|
@ -104,11 +103,9 @@ let root: Root | null = null;
|
|||
let container: HTMLDivElement | null = null;
|
||||
|
||||
async function act(callback: () => void | Promise<void>) {
|
||||
let result: void | Promise<void> = undefined;
|
||||
flushSync(() => {
|
||||
result = callback();
|
||||
await reactAct(async () => {
|
||||
await callback();
|
||||
});
|
||||
await result;
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -1043,11 +1040,6 @@ describe("install-time agent enablement", () => {
|
|||
/>,
|
||||
);
|
||||
});
|
||||
// The dialog seeds its slug/agent state in passive effects; give them a
|
||||
// macrotask to flush before interacting.
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
|
||||
const node = container as ParentNode;
|
||||
expect(node.textContent).toContain("Enable for agents");
|
||||
|
|
@ -1089,15 +1081,9 @@ describe("install-time agent enablement", () => {
|
|||
|
||||
// Dialog opens before the agents query resolves: nothing to select yet.
|
||||
await act(async () => renderDialog([]));
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
|
||||
// The agents arrive later; the untouched selection must pick them up.
|
||||
await act(async () => renderDialog(agentOptions));
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
|
||||
await click(buttonsNamed(container as ParentNode, "Install skill")[0] as HTMLButtonElement);
|
||||
|
||||
|
|
@ -1129,9 +1115,6 @@ describe("install-time agent enablement", () => {
|
|||
/>,
|
||||
);
|
||||
});
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
|
||||
const node = container as ParentNode;
|
||||
expect(node.textContent).not.toContain("Enable for agents");
|
||||
|
|
|
|||
Loading…
Reference in New Issue