From 916e647a756f270b2a86fb63bc2d5f52affe9c64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 24 Oct 2026 10:45:01 +0800 Subject: [PATCH] chore(deps-dev): bump happy-dom from 20.11.1 to 21.0.4 in /frontend (#7391) * chore(deps-dev): bump happy-dom from 20.11.1 to 21.0.4 in /frontend Bumps [happy-dom](https://github.com/capricorn86/happy-dom) from 20.11.1 to 21.0.4. - [Release notes](https://github.com/capricorn86/happy-dom/releases) - [Commits](https://github.com/capricorn86/happy-dom/compare/v20.11.1...v21.0.4) --- updated-dependencies: - dependency-name: happy-dom dependency-version: 21.0.4 dependency-type: direct:development ... Signed-off-by: dependabot[bot] * test(frontend): isolate FlipDisplay animations in DOM suites --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Willem Jiang --- frontend/AGENTS.md | 17 ++++++---- frontend/package.json | 2 +- frontend/pnpm-lock.yaml | 32 +++++++++---------- .../messages/subtask-card.dom.test.tsx | 8 +++++ .../messages/tool-call-details.dom.test.tsx | 8 +++++ frontend/tests/unit/helpers/flip-display.tsx | 17 ++++++++++ 6 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 frontend/tests/unit/helpers/flip-display.tsx diff --git a/frontend/AGENTS.md b/frontend/AGENTS.md index 0b58946a46..13870c6e2f 100644 --- a/frontend/AGENTS.md +++ b/frontend/AGENTS.md @@ -27,18 +27,21 @@ Run from `frontend/`; host pnpm calls use `../scripts/pnpm.py`. - `pnpm format` / `pnpm format:write`: Prettier check/write. - `pnpm test`: Rstest unit tests; `pnpm test:e2e`: Playwright Chromium E2E tests. -Rstest unit tests under `tests/unit/` mirror `src/` (e.g., `tests/unit/core/api/stream-mode.test.ts` tests `src/core/api/stream-mode.ts`). Import source modules via `@/`. +Unit tests under `tests/unit/` mirror `src/`; import source via `@/`. Webpack is the default development bundler. Use `DEER_FLOW_DEV_BUNDLER=turbo` with `pnpm dev` to opt in to Turbopack when diagnosing a local Next.js bundler issue. On Windows `pnpm dev` binds `127.0.0.1` by default because Hyper-V/winnat excluded port ranges can reject Next's default `0.0.0.0` bind with `EACCES` (#2870). Pass `pnpm dev -- --hostname 0.0.0.0` to listen on a LAN interface instead. -`rstest.config.ts` separates **node** (`*.test.ts` / `*.test.tsx`) for pure logic -from **happy-dom** (`*.dom.test.ts` / `*.dom.test.tsx`) for components and hooks -rendered with `@testing-library/react`'s `renderHook`. Keep the split: DOM tests -cost roughly 3x more runtime. Hooks that depend on React effect ordering, unmount -cleanup, or re-renders on store changes belong in `.dom.test.*`; do not mock React -in node tests to cover those behaviors. +`rstest.config.ts`: **node** runs `*.test.*` pure logic; **happy-dom** runs +`*.dom.test.*` components/hooks via `@testing-library/react` render/renderHook. +DOM costs ~3x: keep the split. Effect ordering, unmount cleanup and store +re-renders need DOM tests with real React. + +Content/state suites may mock decorative `FlipDisplay` with +`tests/unit/helpers/flip-display.tsx`, preserving children, classes and keyed +remounts. Happy DOM 21's animation cancellation rejects `finished`; keep rejection +reporting enabled. Real Motion behavior belongs in Playwright. E2E tests live under `tests/e2e/` and use Playwright with Chromium. They mock all backend APIs via `page.route()` network interception and test real page interactions (navigation, chat input, streaming responses). Config: `playwright.config.ts`. The real-backend auth contract in `tests/e2e-real-backend/auth-disabled-contract.spec.ts` and `backend/tests/test_auth_me_permissions.py` pin the complete route-permission list; update both when adding registered permissions (including `projects:read/write/delete`). diff --git a/frontend/package.json b/frontend/package.json index 4e015714a6..d3ecea5361 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -117,7 +117,7 @@ "@types/react-dom": "^19.0.0", "eslint": "^9.23.0", "eslint-config-next": "^15.2.3", - "happy-dom": "^20.11.1", + "happy-dom": "^21.0.4", "postcss": "^8.5.18", "prettier": "^3.5.3", "prettier-plugin-tailwindcss": "^0.6.11", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 218ae8bce4..40f3487f86 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -266,7 +266,7 @@ importers: version: 2.1.0(@rsbuild/core@2.0.15)(@rspack/core@2.0.8(@swc/helpers@0.5.23)) '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(happy-dom@20.11.1) + version: 0.10.6(happy-dom@21.0.4) '@tailwindcss/postcss': specifier: ^4.0.15 version: 4.1.18 @@ -295,8 +295,8 @@ importers: specifier: ^15.2.3 version: 15.5.12(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) happy-dom: - specifier: ^20.11.1 - version: 20.11.1 + specifier: ^21.0.4 + version: 21.0.4 postcss: specifier: ^8.5.18 version: 8.5.25 @@ -2536,8 +2536,8 @@ packages: '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/ws@8.18.2': + resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==} '@typescript-eslint/eslint-plugin@8.55.0': resolution: {integrity: sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==} @@ -3853,8 +3853,8 @@ packages: hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} - happy-dom@20.11.1: - resolution: {integrity: sha512-XSt8tMzbW9ymE7687xztkO1ckR7qJNQ3LywY9vlYGhGi3zXrGBHuUo2Cl1ztZaICW+1eAGdkLbj6iwVqDT33kg==} + happy-dom@21.0.4: + resolution: {integrity: sha512-tFm+GaLBgo6o0awHnvHaNoraVo27qJ+2tZEtZ+cIa08hXbeitrxAJajLI05hsUy/2/YTKcUjQYzHe5mCcraLBw==} engines: {node: '>=20.0.0'} has-bigints@1.1.0: @@ -5954,8 +5954,8 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - ws@8.21.1: - resolution: {integrity: sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==} + ws@8.22.0: + resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -7795,12 +7795,12 @@ snapshots: optionalDependencies: '@rspack/core': 2.0.8(@swc/helpers@0.5.23) - '@rstest/core@0.10.6(happy-dom@20.11.1)': + '@rstest/core@0.10.6(happy-dom@21.0.4)': dependencies: '@rsbuild/core': 2.0.15 '@types/chai': 5.2.3 optionalDependencies: - happy-dom: 20.11.1 + happy-dom: 21.0.4 transitivePeerDependencies: - '@module-federation/runtime-tools' - core-js @@ -8250,7 +8250,7 @@ snapshots: '@types/whatwg-mimetype@3.0.2': {} - '@types/ws@8.18.1': + '@types/ws@8.18.2': dependencies: '@types/node': 20.19.33 @@ -9851,15 +9851,15 @@ snapshots: hachure-fill@0.5.2: {} - happy-dom@20.11.1: + happy-dom@21.0.4: dependencies: '@types/node': 20.19.33 '@types/whatwg-mimetype': 3.0.2 - '@types/ws': 8.18.1 + '@types/ws': 8.18.2 buffer-image-size: 0.6.4 entities: 7.0.1 whatwg-mimetype: 3.0.0 - ws: 8.21.1 + ws: 8.22.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -12566,7 +12566,7 @@ snapshots: word-wrap@1.2.5: {} - ws@8.21.1: {} + ws@8.22.0: {} yaml@2.8.3: {} diff --git a/frontend/tests/unit/components/workspace/messages/subtask-card.dom.test.tsx b/frontend/tests/unit/components/workspace/messages/subtask-card.dom.test.tsx index 4229abfbc5..cca3888a42 100644 --- a/frontend/tests/unit/components/workspace/messages/subtask-card.dom.test.tsx +++ b/frontend/tests/unit/components/workspace/messages/subtask-card.dom.test.tsx @@ -25,6 +25,14 @@ import { } from "@/core/tasks/subtask-render"; import type { Subtask } from "@/core/tasks/types"; +import { FlipDisplay as StaticFlipDisplay } from "../../../helpers/flip-display"; + +rs.mock("@/components/workspace/flip-display", () => ({ + FlipDisplay: (props: Parameters[0]) => ( + + ), +})); + rs.mock("@/core/tasks/api", () => ({ fetchSubtaskSteps: rs.fn() })); afterEach(() => { diff --git a/frontend/tests/unit/components/workspace/messages/tool-call-details.dom.test.tsx b/frontend/tests/unit/components/workspace/messages/tool-call-details.dom.test.tsx index e1b7f27b1b..6c7aacd28a 100644 --- a/frontend/tests/unit/components/workspace/messages/tool-call-details.dom.test.tsx +++ b/frontend/tests/unit/components/workspace/messages/tool-call-details.dom.test.tsx @@ -14,6 +14,14 @@ import { I18nContext } from "@/core/i18n/context"; import { enUS } from "@/core/i18n/locales/en-US"; import type { ArtifactEntry } from "@/core/threads/types"; +import { FlipDisplay as StaticFlipDisplay } from "../../../helpers/flip-display"; + +rs.mock("@/components/workspace/flip-display", () => ({ + FlipDisplay: (props: Parameters[0]) => ( + + ), +})); + rs.mock("@/components/workspace/artifacts", () => ({ useArtifacts: () => ({ setOpen: () => undefined, select: () => undefined }), })); diff --git a/frontend/tests/unit/helpers/flip-display.tsx b/frontend/tests/unit/helpers/flip-display.tsx new file mode 100644 index 0000000000..1ae6bbf997 --- /dev/null +++ b/frontend/tests/unit/helpers/flip-display.tsx @@ -0,0 +1,17 @@ +import type { ComponentProps } from "react"; + +import type { FlipDisplay as AnimatedFlipDisplay } from "@/components/workspace/flip-display"; + +// Content/state tests keep real React behavior without exercising Motion's +// browser animation lifecycle in Happy DOM. Preserve keyed child remounts. +export function FlipDisplay({ + uniqueKey, + children, + className, +}: ComponentProps) { + return ( +
+
{children}
+
+ ); +}