diff --git a/.agents/skills/frontend-testing/SKILL.md b/.agents/skills/frontend-testing/SKILL.md
index 21c46d75bc9..e0a1d4dccae 100644
--- a/.agents/skills/frontend-testing/SKILL.md
+++ b/.agents/skills/frontend-testing/SKILL.md
@@ -102,11 +102,11 @@ describe('ComponentName', () => {
})
})
- // Props tests (REQUIRED)
+ // Props tests (REQUIRED when props change observable behavior)
describe('Props', () => {
- it('should apply custom className', () => {
- render()
- expect(screen.getByRole('button')).toHaveClass('custom')
+ it('should disable the action when disabled', () => {
+ render()
+ expect(screen.getByRole('button')).toBeDisabled()
})
})
@@ -220,6 +220,7 @@ Every test should clearly separate:
### 2. Black-Box Testing
- Test observable behavior, not implementation details
+- Test product contracts, not cosmetic implementation. Do not add or expand unit tests only to lock pure style classes, spacing, colors, backgrounds, or layout micro-adjustments. Cover visual-only fixes with browser/manual verification, screenshots, or E2E/visual checks when risk justifies it. Add unit tests only when the change affects user-observable behavior, accessibility semantics, state, data flow, routing, or a stable component API contract.
- Use semantic queries (`getByRole` with accessible `name`, `getByLabelText`, `getByPlaceholderText`, `getByText`, and scoped `within(...)`)
- Treat `getByTestId` as a last resort. If a control cannot be found by role/name, label, landmark, or dialog scope, fix the component accessibility first instead of adding or relying on `data-testid`.
- Remove production `data-testid` attributes when semantic selectors can cover the behavior. Keep them only for non-visual mocked boundaries, editor/browser shims such as Monaco, canvas/chart output, or third-party widgets with no accessible DOM in the test environment.
@@ -273,7 +274,7 @@ it('should disable input when isReadOnly is true')
### Always Required (All Components)
1. **Rendering**: Component renders without crashing
-1. **Props**: Required props, optional props, default values
+1. **Props**: Required props, optional props, default values that change observable behavior. Do not test pass-through styling props such as `className` unless they are an explicit, stable component API whose absence would break a real integration contract.
1. **Edge Cases**: null, undefined, empty values, boundary conditions
### Conditional (When Present)
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index d44b89c95d9..00dae047e04 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -151,9 +151,5 @@ jobs:
run: |
vp exec eslint --concurrency=2 --prune-suppressions --quiet || true
- - name: Prune unused i18n
- if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true'
- run: vp run dify-web#i18n:prune-unused --write
-
- if: github.event_name != 'merge_group'
uses: autofix-ci/action@c5b2d67aa2274e7b5a18224e8171550871fc7e4a # v1.3.4
diff --git a/web/app/layout.tsx b/web/app/layout.tsx
index 079ae1f6570..7eaf7b8f432 100644
--- a/web/app/layout.tsx
+++ b/web/app/layout.tsx
@@ -52,7 +52,7 @@ const LocaleLayout = async ({
diff --git a/web/docs/test.md b/web/docs/test.md
index 318b6f27915..76a98b46e01 100644
--- a/web/docs/test.md
+++ b/web/docs/test.md
@@ -46,6 +46,7 @@ pnpm test path/to/file.spec.tsx
- **Semantic naming**: Use `should when ` and group related cases with `describe()`.
- **AAA / Given–When–Then**: Separate Arrange, Act, and Assert clearly with code blocks or comments.
- **Minimal but sufficient assertions**: Keep only the expectations that express the essence of the behavior.
+- **Test product contracts, not cosmetic implementation**: Do not add or expand unit tests only to lock pure style classes, spacing, colors, backgrounds, or layout micro-adjustments. Cover visual-only fixes with browser/manual verification, screenshots, or E2E/visual checks when risk justifies it. Add unit tests only when the change affects user-observable behavior, accessibility semantics, state, data flow, routing, or a stable component API contract.
- **Reusable test data**: Prefer test data builders or factories over hard-coded masses of data.
- **De-flake**: Control time, randomness, network, concurrency, and ordering.
- **Fast & stable**: Keep unit tests running in milliseconds; reserve integration tests for cross-module behavior with isolation.
@@ -179,7 +180,7 @@ Apply the following test scenarios based on component features:
### 2. Props Testing (REQUIRED - All Components)
-Exercise the prop combinations that change observable behavior. Show how required props gate functionality, how optional props fall back to their defaults, and how invalid combinations surface through user-facing safeguards. Let TypeScript catch structural issues; keep runtime assertions focused on what the component renders or triggers.
+Exercise the prop combinations that change observable behavior. Show how required props gate functionality, how optional props fall back to their defaults, and how invalid combinations surface through user-facing safeguards. Let TypeScript catch structural issues; keep runtime assertions focused on what the component renders or triggers. Do not test pass-through styling props such as `className` unless they are an explicit, stable component API whose absence would break a real integration contract.
### 3. State Management