backup
This commit is contained in:
111
Docs/Tasks.md
111
Docs/Tasks.md
@@ -1,111 +0,0 @@
|
||||
## [E2E-5] Config edit saves and persists after page reload
|
||||
|
||||
**Where found:**
|
||||
The `/config` page allows editing jail settings, filter definitions, and server-level options. It is covered by unit tests (`frontend/src/pages/__tests__/ConfigPage.test.tsx`, `backend/tests/test_routers/test_config.py`) but no E2E test verifies that a change made in the UI actually persists through the backend, survives a page reload, and reflects the new value.
|
||||
|
||||
**Why this is needed:**
|
||||
The config page uses an auto-save mechanism (`useAutoSave`) that debounces writes. A regression in the debounce logic, the PATCH endpoint, or the GET-on-mount rehydration would silently discard user edits. Only a full round-trip test can catch this.
|
||||
|
||||
**Goal:**
|
||||
Change a config field value via the UI, wait for the auto-save indicator to confirm the save, reload the page, and assert the new value is still present.
|
||||
|
||||
**What to do:**
|
||||
1. Create `e2e/tests/04_config_edit.robot`.
|
||||
2. Suite Setup: `Login As Admin`.
|
||||
3. Choose a safe, low-risk config field to edit — e.g., the `[DEFAULT]` `bantime` value, or a per-jail `maxretry` setting.
|
||||
4. Record the original value before editing so it can be restored in teardown.
|
||||
5. Test case:
|
||||
```robot
|
||||
*** Settings ***
|
||||
Library Browser
|
||||
Resource ../resources/auth.resource
|
||||
Test Teardown Restore Original Config Value
|
||||
|
||||
*** Test Cases ***
|
||||
Config Field Edit Persists After Reload
|
||||
Login As Admin
|
||||
Go To ${FRONTEND_URL}/config
|
||||
Wait For Elements State css=[role="tablist"] visible timeout=15s
|
||||
# Read current value for teardown
|
||||
${original}= Get Text css=[data-field="bantime"]
|
||||
Set Suite Variable ${ORIGINAL_BANTIME} ${original}
|
||||
# Edit the field
|
||||
Fill Text css=[data-field="bantime"] 7200
|
||||
# Wait for auto-save indicator to show "Saved"
|
||||
Wait For Elements State css=[data-autosave="saved"] visible timeout=15s
|
||||
# Reload and verify persistence
|
||||
Reload
|
||||
Wait For Elements State css=[data-field="bantime"] visible timeout=15s
|
||||
Get Text css=[data-field="bantime"] == 7200
|
||||
|
||||
*** Keywords ***
|
||||
Restore Original Config Value
|
||||
Go To ${FRONTEND_URL}/config
|
||||
Fill Text css=[data-field="bantime"] ${ORIGINAL_BANTIME}
|
||||
Wait For Elements State css=[data-autosave="saved"] visible timeout=15s
|
||||
```
|
||||
6. Also verify via the API that the value was actually written:
|
||||
```robot
|
||||
${resp}= GET ${BACKEND_URL}/api/config expected_status=200
|
||||
Should Contain ${resp.text} 7200
|
||||
```
|
||||
|
||||
**Possible traps and issues:**
|
||||
- The config page auto-save uses a debounce delay. The test must wait for the "Saved" indicator rather than a fixed `Sleep`, otherwise the reload may happen before the PATCH request fires.
|
||||
- The selectors `[data-field="bantime"]` and `[data-autosave="saved"]` do not exist in the current frontend components (no `data-*` attributes on production elements). These must be added to the components before the test can work. See [E2E-6] for the prerequisite task.
|
||||
- Config fields are rendered inside a tab panel. The correct tab must be activated before the target field is interactable. The test must click the right tab first.
|
||||
- If the backend validates the new value and rejects it (e.g., bantime must be a positive integer), the test will fail at the API assertion. Use a value that is guaranteed to be valid.
|
||||
- Editing config files on disk via the API may restart the fail2ban service inside the container, causing a brief health-check failure and destabilising subsequent tests in the suite. Run config edit tests last or use a test-only jail that is isolated from the main config.
|
||||
- Teardown must restore the original value even if the test fails mid-way. Ensure `Test Teardown` is set, not just a final keyword call.
|
||||
|
||||
**Docs changes needed:**
|
||||
- Document the auto-save debounce behaviour and the "Saved" indicator semantics in [Web-Development.md](Web-Development.md) so E2E test authors know what to wait for.
|
||||
- Note in [Testing-Requirements.md](Testing-Requirements.md) that config edit tests must restore state in teardown.
|
||||
|
||||
**Doc references:**
|
||||
- [Web-Development.md](Web-Development.md)
|
||||
- [CONFIGURATION.md](CONFIGURATION.md)
|
||||
- [Testing-Requirements.md](Testing-Requirements.md)
|
||||
- `frontend/src/components/config/__tests__/AutoSaveIndicator.test.tsx`
|
||||
- `frontend/src/hooks/__tests__/useAutoSave.test.ts`
|
||||
- `backend/tests/test_routers/test_config.py`
|
||||
|
||||
---
|
||||
|
||||
## [E2E-6] Add `data-testid` / `data-*` attributes to production frontend components
|
||||
|
||||
**Where found:**
|
||||
Inspecting the frontend source, `data-testid` attributes appear only in test mock files (e.g., `MapPage.test.tsx` line 57: `<div data-testid="world-map" />`). The production components in `frontend/src/components/` and `frontend/src/pages/` have no `data-testid` or `data-*` attributes. E2E tests [E2E-2], [E2E-4], and [E2E-5] all require stable selectors that survive CSS and class-name refactors.
|
||||
|
||||
**Why this is needed:**
|
||||
CSS class selectors and `aria-label` text are brittle — they break when styles change or text is translated. `data-testid` attributes are the idiomatic, refactor-safe way to locate elements in E2E tests. Without them, every UI change risks breaking the E2E suite for reasons unrelated to correctness.
|
||||
|
||||
**Goal:**
|
||||
Key interactive and landmark elements across all pages and the config form have `data-testid` (or semantic `data-*`) attributes that the Robot Framework E2E suite can rely on.
|
||||
|
||||
**What to do:**
|
||||
1. Identify the minimum set of elements needed by the four E2E suites:
|
||||
- `data-testid="page-error-boundary"` on the `PageErrorBoundary` fallback render.
|
||||
- `data-testid="dashboard"`, `data-testid="map-page"`, `data-testid="jails-page"`, `data-testid="history-page"`, `data-testid="blocklists-page"`, `data-testid="config-page"` on each page's root element.
|
||||
- `data-testid="history-table"` on the History page table body.
|
||||
- `data-testid="blocklist-import-button"` on the manual import trigger.
|
||||
- `data-testid="autosave-status"` on the auto-save indicator, with `data-status="saved" | "saving" | "error"`.
|
||||
- `data-field="<fieldname>"` on config input fields that E2E tests will edit.
|
||||
2. Add the attributes directly to the JSX — no wrappers, no extra elements.
|
||||
3. Do not add `data-testid` to elements that already have stable semantic roles (e.g., `<button type="submit">` with unique text, landmark `<main>`, `<nav>`).
|
||||
4. Update the existing vitest component tests to use the new `data-testid` selectors instead of text queries where appropriate.
|
||||
|
||||
**Possible traps and issues:**
|
||||
- `data-testid` attributes are visible in production HTML. This is standard practice and not a security concern, but some teams prefer to strip them in production builds via a Babel/Vite plugin. Decide on a policy before adding them.
|
||||
- Adding attributes to components that are also tested by vitest may require updating those unit tests if they query by `data-testid`.
|
||||
- The `PageErrorBoundary` component wraps lazy-loaded pages. The fallback element must carry the `data-testid` on the rendered fallback JSX, not on the wrapper itself.
|
||||
- Config fields are rendered dynamically from API data. The `data-field` value must be derived from the field's API key name, not a hardcoded index.
|
||||
|
||||
**Docs changes needed:**
|
||||
- Add a "Selector conventions" section to [Web-Development.md](Web-Development.md) documenting when to use `data-testid` vs. semantic selectors vs. ARIA roles, and listing all reserved `data-testid` values used by the E2E suite.
|
||||
|
||||
**Doc references:**
|
||||
- [Web-Development.md](Web-Development.md)
|
||||
- [Testing-Requirements.md](Testing-Requirements.md)
|
||||
- `frontend/src/components/ErrorBoundary.tsx`
|
||||
- `frontend/src/components/config/__tests__/AutoSaveIndicator.test.tsx`
|
||||
@@ -1816,6 +1816,34 @@ The E2E test suite (`e2e/tests/01_page_loading.robot`) verifies every protected
|
||||
|
||||
**Vite SPA note:** All routes return HTTP 200 from the dev server (SPA routing). HTTP status checks are not meaningful — focus on DOM state after client-side navigation.
|
||||
|
||||
### Selector Conventions
|
||||
|
||||
**Principle:** Prefer semantic selectors (role, label, ARIA) over `data-testid`. Use `data-testid` only when semantic selectors are unavailable or too brittle for stable E2E selectors.
|
||||
|
||||
| Selector type | When to use | Example |
|
||||
|---|---|---|
|
||||
| Semantic / ARIA | Interactive elements with clear roles or labels | `button[name="Refresh"]`, `input[aria-label="Ban Time"]` |
|
||||
| `data-testid` | Non-interactive landmarks; elements with no stable semantic cue; dynamically rendered content | Page root `div`, table bodies, blocklist import button |
|
||||
| CSS class | Avoid in E2E — classes change with style refactors | — |
|
||||
|
||||
**Reserved `data-testid` values used by the E2E suite:**
|
||||
|
||||
| `data-testid` | Where | Purpose |
|
||||
|---|---|---|
|
||||
| `page-error-boundary` | `ErrorBoundary` fallback root | E2E-6: detects page-level error fallbacks |
|
||||
| `dashboard` | `DashboardPage` root | E2E-2: dashboard page landmark |
|
||||
| `map-page` | `MapPage` root | E2E-2: world map page landmark |
|
||||
| `jails-page` | `JailsPage` root | E2E-2: jails page landmark |
|
||||
| `history-page` | `HistoryPage` root | E2E-2: history page landmark |
|
||||
| `blocklists-page` | `BlocklistsPage` root | E2E-2: blocklists page landmark |
|
||||
| `config-page` | `ConfigPage` root | E2E-2: config page landmark |
|
||||
| `history-table` | `HistoryPage` table body wrapper | E2E-2: history table body for row assertions |
|
||||
| `blocklist-import-button` | Blocklist "Run Now" button | E2E-4: manual blocklist import trigger |
|
||||
| `autosave-status` | `AutoSaveIndicator` root | E2E-5: auto-save state indicator, carries `data-status="idle\|saving\|saved\|error"` |
|
||||
| `data-field="<fieldname>"` | Config input fields (`ban_time`, `find_time`, `max_retry`, etc.) | E2E-5: targeted field editing |
|
||||
|
||||
**`data-testid` in production:** `data-testid` attributes are visible in production HTML. This is standard practice — they are not a security concern. If your team prefers to strip them in production builds, use a Vite plugin (not done here).
|
||||
|
||||
### Auto-Save Indicator for E2E Tests
|
||||
|
||||
The config page (`/config`) uses `useAutoSave` to debounce edits before sending PATCH requests. E2E tests that edit config fields must wait for the "Saved" indicator rather than using fixed `Sleep`, otherwise the reload may fire before the HTTP request is sent.
|
||||
|
||||
Reference in New Issue
Block a user