mirror of
https://github.com/langgenius/dify.git
synced 2026-08-30 17:11:50 +08:00
refactor: consolidate frontend browser test infrastructure (#40997)
This commit is contained in:
+38
-15
@@ -39,10 +39,22 @@ Use the smallest boundary that includes the behavior owner and proves the produc
|
||||
- Use a real browser for layout, responsive behavior, browser-specific APIs, animation, and focus behavior that `happy-dom` cannot represent faithfully.
|
||||
- Follow `packages/dify-ui/README.md` for the Storybook and Vitest boundary of Dify UI primitives.
|
||||
|
||||
Browser Mode provides a real browser runtime for focused component tests. Using it does not by itself provide end-to-end coverage or prove integration with the running app's authentication, APIs, or persistence.
|
||||
|
||||
Test the behavior owner. Barrel exports, pass-through wrappers, and purely presentational children do not need separate tests when the owning feature already proves their contract. Do not repeat generic behavior already owned by Base UI, React Aria, or the browser; test Dify's integration, overrides, and known regressions.
|
||||
|
||||
### Browser Mode Admission
|
||||
|
||||
`happy-dom` is the default choice for tests under `web/`. Use the `unit` project for pure logic, hooks, and DOM-observable component or feature behavior that does not depend on a browser's rendering engine. This split follows [Vitest test projects] and [Why Browser Mode].
|
||||
|
||||
Use the `browser` project only when the asserted contract depends on browser-owned behavior that `happy-dom` cannot represent faithfully, such as:
|
||||
|
||||
- Layout geometry, CSS hit testing, responsive behavior, or pointer targeting.
|
||||
- Native focus, selection, scrolling, keyboard, or pointer behavior.
|
||||
- Browser APIs, observers, or animation lifecycles whose real implementation affects the result.
|
||||
|
||||
Rendering UI, reducing mocks, increasing confidence, or raising coverage is not enough reason to use Browser Mode. Each `*.browser.spec.{ts,tsx}` test under `web/app/` must name the browser-owned behavior and why `happy-dom` is insufficient, exercise the smallest owner through semantic locators, and justify its additional runtime. Do not use forced interaction, fixed sleeps, private DOM or CSS assertions, or real network requests.
|
||||
|
||||
Browser Mode remains a focused component or feature test and currently proves Chromium only. Use the end-to-end suite for a running application, authentication, real routing, backend APIs, persistence, or complete journeys.
|
||||
|
||||
## Assert Behavior, Not Implementation
|
||||
|
||||
- Drive state transitions through props, user interaction, URL changes, or public APIs.
|
||||
@@ -103,8 +115,9 @@ Mocks must preserve the public contract needed by the test. Do not mock interact
|
||||
|
||||
## Dify Test Setup
|
||||
|
||||
- Tests under `web/` run in `happy-dom` through `web/vite.config.ts` and load `web/vitest.setup.ts`.
|
||||
- Tests under `packages/dify-ui/` use separate Vitest Browser Mode projects: unit specs load the package styles through `vitest.setup.ts`, while Storybook tests run stories through `@storybook/addon-vitest`.
|
||||
- Following [Vite+ testing configuration], tests under `web/` use two explicit projects in `web/vite.config.ts`. Supported commands and CI select one project explicitly: `unit` runs in `happy-dom` and loads `web/vitest.setup.ts`, while `browser` runs matching `app/**/*.browser.spec.{ts,tsx}` files in Playwright Chromium and loads `web/vitest.browser.setup.ts`. Bare `vp test` runs both registered projects.
|
||||
- Browser failures keep screenshots and Playwright traces under `web/.vitest-browser/`. CI uploads that directory only when failure artifacts exist; Browser Mode does not own coverage or report merging.
|
||||
- Tests under `packages/dify-ui/` use two Chromium Browser Mode projects: `unit` owns focused primitive contracts and loads the package styles through `vitest.setup.ts`; `storybook` owns story render, play, and accessibility contracts through `@storybook/addon-vitest`. The names identify behavior owners, not different runtimes.
|
||||
- New component and feature specs should generally use a sibling `__tests__/` directory. Existing colocated utility and hook specs may follow their owning module's convention. Cross-feature integration specs belong in `web/__tests__/`.
|
||||
- The shared `react-i18next` mock is loaded globally. Use `createReactI18nextMock` from `web/test/i18n-mock` only when a test needs custom translations.
|
||||
- For `nuqs` behavior, use the helpers in `web/test/nuqs-testing.tsx` and assert URL updates. Mock `nuqs` only when URL synchronization is explicitly outside the test contract.
|
||||
@@ -127,19 +140,21 @@ When working across several files, order the work by dependency and verify each
|
||||
Run from `web/`:
|
||||
|
||||
```bash
|
||||
# Focused spec or directory
|
||||
vp test run path/to/spec-or-directory
|
||||
# happy-dom; omit the path to run the full unit project
|
||||
vp test run --project unit path/to/spec-or-directory
|
||||
|
||||
# All web tests
|
||||
vp test run
|
||||
# Browser Mode; omit the path to run the full browser project
|
||||
vp test run --project browser path/to/spec.browser.spec.tsx
|
||||
|
||||
# Watch mode
|
||||
vp test watch path/to/spec
|
||||
# Watch mode; select browser instead for Browser Mode
|
||||
vp test watch --project unit path/to/spec
|
||||
|
||||
# Diagnostic coverage report; not an acceptance target
|
||||
vp test run --coverage path/to/spec-or-directory
|
||||
# Diagnostic coverage report for the unit project; not an acceptance target
|
||||
vp test run --project unit --coverage path/to/spec-or-directory
|
||||
```
|
||||
|
||||
Always pass `--project unit` or `--project browser`. Bare `vp test` runs both registered projects and is not the standard Web test command.
|
||||
|
||||
## Review Checklist
|
||||
|
||||
- Does each test protect a reachable product contract or meaningful regression?
|
||||
@@ -149,12 +164,16 @@ vp test run --coverage path/to/spec-or-directory
|
||||
- Is the suite deterministic, focused, and cheaper to maintain than the regression it prevents?
|
||||
- Would the test survive a refactor that preserves behavior?
|
||||
- Can the reviewer name one realistic regression and the assertion that would fail?
|
||||
- For Browser Mode, is the browser-owned contract explicit, impossible to prove faithfully in `happy-dom`, and worth the additional runtime?
|
||||
|
||||
## References
|
||||
|
||||
- [Vitest documentation]
|
||||
- [Vitest test projects]
|
||||
- [Why Browser Mode]
|
||||
- [Vitest Browser Mode documentation]
|
||||
- [Vitest Browser Mode locators]
|
||||
- [Vitest Browser Mode traces]
|
||||
- [Storybook Vitest addon]
|
||||
- [Testing Library guiding principles]
|
||||
- [React Testing Library documentation]
|
||||
@@ -166,6 +185,10 @@ vp test run --coverage path/to/spec-or-directory
|
||||
[Testing Library guiding principles]: https://testing-library.com/docs/guiding-principles
|
||||
[Testing Library query guidance]: https://testing-library.com/docs/queries/about
|
||||
[Testing Library user-event guidance]: https://testing-library.com/docs/user-event/intro
|
||||
[Vitest Browser Mode documentation]: https://vitest.dev/guide/browser
|
||||
[Vitest Browser Mode locators]: https://vitest.dev/api/browser/locators
|
||||
[Vitest documentation]: https://vitest.dev/guide
|
||||
[Vite+ testing configuration]: https://viteplus.dev/guide/test
|
||||
[Vitest Browser Mode documentation]: https://v4.vitest.dev/guide/browser
|
||||
[Vitest Browser Mode locators]: https://v4.vitest.dev/api/browser/locators
|
||||
[Vitest Browser Mode traces]: https://v4.vitest.dev/guide/browser/trace-view
|
||||
[Vitest documentation]: https://v4.vitest.dev/guide
|
||||
[Vitest test projects]: https://v4.vitest.dev/guide/projects
|
||||
[Why Browser Mode]: https://v4.vitest.dev/guide/browser/why
|
||||
|
||||
Reference in New Issue
Block a user