| @@ -0,0 +1,166 @@ | |||||
| # E2E Test Foundation Design | |||||
| ## Goal | |||||
| Build a reusable end-to-end test foundation for the admin console, then use the model multidimensional pricing page as the first covered workflow. | |||||
| The foundation must verify the real frontend/backend contract, authentication, persistence, and page routing. It should be easy to run locally and suitable for CI later. | |||||
| ## Scope | |||||
| In scope: | |||||
| - Add a Playwright-based E2E test foundation under `web/`. | |||||
| - Run the React frontend through Vite. | |||||
| - Run the Go backend against an isolated SQLite database. | |||||
| - Log in as the generated root user. | |||||
| - Cover the model multidimensional pricing workflow under `/console/setting?tab=ratio`. | |||||
| - Keep tests deterministic by using temporary files, fixed ports, and isolated storage state. | |||||
| Out of scope for the first pass: | |||||
| - Docker Compose E2E. | |||||
| - MySQL/PostgreSQL E2E matrix. | |||||
| - Full relay calls to upstream AI providers. | |||||
| - Broad admin console coverage outside the model pricing workflow. | |||||
| ## Recommended Approach | |||||
| Use real backend + temporary SQLite + Playwright. | |||||
| The project already has `@playwright/test` in `web/package.json`. The backend can start with `go run main.go`, and when no users exist it creates the root user with username `root` and password `123456`. Running against a temporary SQLite database gives each test run a clean system without requiring external services. | |||||
| This approach is slower than API mocks, but it catches the issues that matter for this feature: frontend/backend response shape, save/load behavior, auth redirects, and persistence across page reloads. | |||||
| ## Runtime Architecture | |||||
| Playwright will run from the `web/` directory. | |||||
| Backend: | |||||
| - Started by a Playwright global setup helper. | |||||
| - Command: `go run main.go` from the repository root. | |||||
| - Environment: | |||||
| - `PORT=3001` | |||||
| - `SQLITE_PATH=<temp-dir>/e2e.db?_busy_timeout=30000` | |||||
| - `SESSION_SECRET=e2e_session_secret_for_local_tests` | |||||
| - The helper waits for `/api/setup` or another lightweight HTTP endpoint before running tests. | |||||
| - The helper stores backend process metadata so global teardown can stop it. | |||||
| Frontend: | |||||
| - Started by Playwright `webServer`. | |||||
| - Command: `bun run dev -- --host 127.0.0.1 --port 5173` | |||||
| - Environment: | |||||
| - `VITE_REACT_APP_SERVER_URL=http://127.0.0.1:3001` | |||||
| - Base URL: `http://127.0.0.1:5173` | |||||
| Browser auth: | |||||
| - A setup project logs in once as `root / 123456`. | |||||
| - The authenticated browser state is saved to `web/e2e/.auth/root.json`. | |||||
| - Feature tests reuse that storage state. | |||||
| ## Test Layout | |||||
| Proposed files: | |||||
| - `web/playwright.config.js` | |||||
| - `web/e2e/global-setup.js` | |||||
| - `web/e2e/global-teardown.js` | |||||
| - `web/e2e/auth.setup.js` | |||||
| - `web/e2e/model-pricing.spec.js` | |||||
| - `web/e2e/utils/process.js` | |||||
| - `web/e2e/utils/wait.js` | |||||
| Proposed package scripts: | |||||
| - `e2e`: `playwright test` | |||||
| - `e2e:ui`: `playwright test --ui` | |||||
| - `e2e:headed`: `playwright test --headed` | |||||
| - `e2e:install`: `playwright install chromium` | |||||
| ## First Workflow: Model Multidimensional Pricing | |||||
| The first E2E test should cover the critical user path: | |||||
| 1. Open `/console/setting?tab=ratio`. | |||||
| 2. Confirm the admin setting page loads. | |||||
| 3. Open the `模型多维计费` tab. | |||||
| 4. Create or edit pricing for a deterministic test model name, for example `e2e-video-pricing-model`. | |||||
| 5. Add dimensions such as `duration` and `quality`. | |||||
| 6. Use the generator to produce a linear pricing table. | |||||
| 7. Save the config. | |||||
| 8. Reload the page. | |||||
| 9. Reopen the same model config. | |||||
| 10. Assert that dimensions and generated rows are loaded. | |||||
| The test should also observe the network response for save/load requests and assert successful API envelopes where practical. This makes contract mismatches visible even if the UI shows a generic toast. | |||||
| ## Selectors | |||||
| Prefer stable selectors instead of brittle text-only selectors for controls that are hard to disambiguate. | |||||
| The implementation should add `data-testid` only where current markup cannot be selected reliably: | |||||
| - model pricing tab container | |||||
| - create/edit model pricing button | |||||
| - model name input | |||||
| - dimension editor add row button | |||||
| - generator open/apply buttons | |||||
| - save button | |||||
| Visible text can still be used for high-level navigation when the text is unique and user-facing. | |||||
| ## Data Isolation | |||||
| Each E2E run uses a new temporary SQLite database path. This prevents tests from depending on local developer data and avoids cleanup requirements for most tables. | |||||
| Within the UI, test-created models should use an `e2e-` prefix. If the same database is reused during debugging, tests can safely identify their own records. | |||||
| ## Failure Artifacts | |||||
| Playwright should collect useful artifacts on failure: | |||||
| - screenshot: only on failure | |||||
| - trace: retain on failure | |||||
| - video: off by default for speed | |||||
| These defaults keep normal runs fast while still making UI failures diagnosable. | |||||
| ## CI Path | |||||
| The initial implementation should work locally first. CI can later run: | |||||
| 1. `cd web && bun install` | |||||
| 2. `cd web && bun run e2e:install` | |||||
| 3. `cd web && bun run e2e` | |||||
| No external database or service should be required for the first workflow. | |||||
| ## Risks And Mitigations | |||||
| Backend startup can be slow. | |||||
| - Mitigation: wait on an HTTP endpoint with a clear timeout and useful logs. | |||||
| Ports can be occupied locally. | |||||
| - Mitigation: use fixed defaults first for simplicity, but allow overrides through `E2E_BACKEND_PORT` and `E2E_FRONTEND_PORT`. | |||||
| Chinese UI text may be rendered through i18n and encoding-sensitive files. | |||||
| - Mitigation: prefer `data-testid` for critical controls and keep user-facing text assertions limited to stable labels. | |||||
| Playwright browsers may not be installed. | |||||
| - Mitigation: provide `bun run e2e:install` and document it in script names. | |||||
| ## Acceptance Criteria | |||||
| - `cd web && bun run e2e` starts the backend and frontend automatically. | |||||
| - The run uses an isolated SQLite database. | |||||
| - The test logs in as root without manual steps. | |||||
| - The model multidimensional pricing workflow can save and reload a generated config. | |||||
| - Failing tests produce a trace and screenshot. | |||||
| - Existing unit tests and frontend build remain runnable without depending on E2E setup. | |||||