@@ -21,7 +21,7 @@ Use this guide to review both code and workflow. Focus on Mendix pluggable widge
2121 - Else: conventional commits (e.g., ` feat: ... ` , ` fix: ... ` ).
2222- ** Template adherence** (see ` .github/pull_request_template.md ` ):
2323 - Lint/test locally: ` pnpm lint ` , ` pnpm test ` .
24- - New tests for features/bug fixes.
24+ - New tests for features/bug fixes (unit tests in ` src/**/__tests__/*.spec.ts ` , E2E tests in ` e2e/*.spec.js ` ) .
2525 - Related PRs linked if applicable.
2626 - If XML or behavior changes: ask for docs PR link in ` mendix/docs ` .
2727- ** Multi-package PRs** : Validate each changed package separately.
@@ -128,7 +128,7 @@ Use this guide to review both code and workflow. Focus on Mendix pluggable widge
128128- Code or XML changed in ` packages/**/<pkg>/ ` but no version bump or ` CHANGELOG.md ` :
129129 - " Behavior changed but no version bump or `CHANGELOG.md`. Please bump semver and add changelog (you can use `pnpm -w changelog`)."
130130- Features / bug fixes without tests :
131- - " Please add/adjust unit tests in `src/__tests__/` to cover this change."
131+ - " Please add/adjust unit tests in `src/components/ __tests__/` or component tests to cover this change. For user-facing features, consider adding E2E tests in `e2e/` ."
132132- XML changes without TS alignment :
133133 - " XML props changed but TS props/usage aren't aligned. Please update the component props/types and usage."
134134
@@ -170,6 +170,143 @@ Use this guide to review both code and workflow. Focus on Mendix pluggable widge
170170
171171- Prefer root -cause layout /size fixes instead of programmatic scroll resets .
172172
173+ ## Testing requirements and best practices
174+
175+ ### Testing strategy overview
176+
177+ This repository uses a comprehensive three -tier testing strategy :
178+
179+ 1. **Unit tests ** (Jest + React Testing Library ) - Test individual components and functions in isolation
180+ 2. **Component tests ** - Test React components with Mendix data integration and user interactions
181+ 3. **E2E tests ** (Playwright ) - Test complete user workflows in real Mendix applications
182+
183+ ### Unit testing (Jest + RTL )
184+
185+ - **Location **: `src /components /__tests__ /* .spec.ts` or `src/__tests__/*.spec.ts`
186+ - **Tools**: Jest, React Testing Library (enzyme-free configuration), `@mendix/widget-plugin-test-utils`
187+ - **Config**: Each package uses `@mendix/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js`
188+ - **Command**: `pnpm test` (package-level) or `pnpm -w test` (workspace-level)
189+
190+ #### Unit test requirements
191+
192+ - **New features**: Must include unit tests covering all logic branches and edge cases
193+ - **Bug fixes**: Add regression tests that would have caught the original bug
194+ - **Component props**: Test all prop combinations, especially error states and loading states
195+ - **Mendix data handling**: Mock Mendix APIs using builders from `@mendix/widget-plugin-test-utils`:
196+
197+ ```ts
198+ import { dynamicValue, EditableValueBuilder } from "@mendix/widget-plugin-test-utils";
199+
200+ const mockValue = new EditableValueBuilder().withValue("test").build();
201+ ```
202+
203+ - **Error boundaries**: Test error states and graceful fallbacks
204+ - **Accessibility**: Include basic a11y assertions (roles, labels, ARIA attributes)
205+ - **Snapshot tests**: Use sparingly, only for complex DOM structures that are unlikely to change
206+
207+ #### Unit test patterns to review
208+
209+ - **Test file naming**: Must follow `*.spec.ts` convention
210+ - **Test descriptions**: Clear, behavior-focused descriptions ("renders loading state when data is unavailable")
211+ - **Mocking strategy**: Prefer `@mendix/widget-plugin-test-utils` builders over manual mocks
212+ - **Async testing**: Proper use of `waitFor`, `findBy*` queries for async operations
213+ - **Cleanup**: Ensure tests don't leak state between runs
214+
215+ ### Component testing
216+
217+ - **Scope**: Test React components integrated with Mendix data layer
218+ - **Focus**: User interactions, data binding, prop changes, widget lifecycle
219+ - **Tools**: Same as unit tests but with full Mendix context and data sources
220+
221+ #### Component test requirements
222+
223+ - **Mendix data integration**: Test with various Mendix data states (loading, empty, error, success)
224+ - **User interactions**: Test clicks, form submissions, keyboard navigation
225+ - **Widget lifecycle**: Test component mount/unmount, prop updates, re-renders
226+ - **Data mutations**: Test `EditableValue.setValue()`, `ActionValue.execute()` calls
227+ - **Validation**: Test form validation, error messages, required field handling
228+
229+ ### E2E testing (Playwright)
230+
231+ - **Location**: `e2e/*.spec.js` in each widget package
232+ - **Tools**: Playwright with custom Mendix test project setup via `automation/run-e2e`
233+ - **Config**: `automation/run-e2e/playwright.config.cjs`
234+ - **Commands**:
235+ - `pnpm e2edev` - Development mode with GUI debugger
236+ - `pnpm e2e` - CI mode (headless)
237+
238+ #### E2E test requirements
239+
240+ - **Complete workflows**: Test end-to-end user journeys, not just individual widgets
241+ - **Cross-browser**: Tests run in Chromium (CI extends to other browsers)
242+ - **Visual regression**: Use `toHaveScreenshot()` for visual consistency
243+ - **Data scenarios**: Test with various data configurations from test projects
244+ - **Accessibility**: Include `@axe-core/playwright` accessibility scans
245+ - **Session cleanup**: Always cleanup Mendix sessions to avoid license limits:
246+ ```js
247+ test.afterEach("Cleanup session", async ({ page }) => {
248+ await page.evaluate(() => window.mx.session.logout());
249+ });
250+ ```
251+
252+ #### E2E test structure
253+
254+ - **Test project**: Each widget has dedicated test project in GitHub (`testProject.githubUrl`, `testProject.branchName`)
255+ - **Page setup**: Use `page.goto("/")` and `page.waitForLoadState("networkidle")`
256+ - **Selectors**: Prefer `mx-name-*` class selectors for Mendix widgets
257+ - **Assertions**: Combine element visibility, screenshot comparisons, and content verification
258+
259+ ### Testing coverage expectations
260+
261+ #### For new features
262+
263+ - **Unit tests**: 80%+ code coverage, all public methods and edge cases
264+ - **Component tests**: Key user interactions and data integration points
265+ - **E2E tests**: At least one happy path and one error scenario
266+
267+ #### For bug fixes
268+
269+ - **Regression test**: Unit or component test that reproduces the original bug
270+ - **Fix verification**: Test that confirms the fix works correctly
271+ - **Edge case coverage**: Additional tests for similar potential issues
272+
273+ #### For refactoring
274+
275+ - **Test preservation**: All existing tests should continue to pass
276+ - **Test updates**: Update tests if public APIs change, but avoid unnecessary changes
277+ - **Coverage maintenance**: Code coverage should not decrease
278+
279+ ### Test-related heuristics for Copilot
280+
281+ #### Missing test coverage
282+
283+ - New React components without corresponding `.spec.ts` files:
284+ - "New component `ComponentName` is missing unit tests. Please add tests in `src/components/__tests__/ComponentName.spec.ts`."
285+ - Features affecting user workflows without E2E tests:
286+ - "This feature changes user interaction patterns. Please add E2E tests in `e2e/WidgetName.spec.js` or update existing ones."
287+ - Bug fixes without regression tests:
288+ - "Bug fix detected but no regression test found. Please add a test that would have caught this issue."
289+
290+ #### Test quality issues
291+
292+ - Tests using deprecated Enzyme patterns:
293+ - "Please migrate from Enzyme to React Testing Library using `render()` and `screen` queries."
294+ - Hard-coded test data instead of builders:
295+ - "Consider using `@mendix/widget-plugin-test-utils` builders instead of hardcoded mocks for better maintainability."
296+ - E2E tests without session cleanup:
297+ - "E2E tests must include session cleanup to avoid Mendix license limit issues. Add `test.afterEach()` with logout."
298+ - Snapshot tests for dynamic content:
299+ - "Avoid snapshot tests for dynamic content. Use specific assertions instead."
300+
301+ #### Test configuration issues
302+
303+ - Custom Jest config without extending base config:
304+ - "Widget Jest config should extend `@mendix/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js`."
305+ - Missing test project configuration for E2E:
306+ - "Widget package.json missing `testProject.githubUrl` and `testProject.branchName` for E2E tests."
307+ - E2E specs not following naming convention:
308+ - "E2E test files should follow `WidgetName.spec.js` naming convention in `e2e/` directory."
309+
173310## Scope/Noise reduction
174311
175312- Focus on: `src/**`, `*.xml`, `*.scss`, `package.json`, `CHANGELOG.md`, build/test config changes.
@@ -178,8 +315,10 @@ Use this guide to review both code and workflow. Focus on Mendix pluggable widge
178315## Quick commands
179316
180317- Lint: `pnpm lint`
181- - Test: `pnpm test`
318+ - Test: `pnpm test` (unit tests)
182319- Build: `pnpm build`
320+ - E2E (dev): `pnpm e2edev` (with GUI debugger)
321+ - E2E (CI): `pnpm e2e` (headless)
183322- Prepare changelog/version (workspace): `pnpm -w changelog`, `pnpm -w version`
184323
185324## Tone and format for comments
0 commit comments