-
Notifications
You must be signed in to change notification settings - Fork 5
feat: Implement E2E user journey tests with auth bypass #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,239 @@ | ||
| # E2E User Journey Tests - Implementation Notes | ||
|
|
||
| ## Overview | ||
|
|
||
| This document describes the implementation of comprehensive E2E tests that validate complete user journeys through actual UI interactions, rather than bypassing flows through database seeding. | ||
|
|
||
| ## Test Files Created | ||
|
|
||
| ### 1. `test_auth_flow.spec.ts` (4 test cases) | ||
| - Login page rendering | ||
| - Successful login with valid credentials | ||
| - Error handling for invalid credentials | ||
| - Logout functionality | ||
|
|
||
| ### 2. `test_project_creation.spec.ts` (3 test cases) | ||
| - Root page display with create project option | ||
| - Creating new project via UI | ||
| - Form validation for required fields | ||
|
|
||
| ### 3. `test_start_agent_flow.spec.ts` (3 test cases) | ||
| - Starting Socratic discovery from dashboard | ||
| - Answering discovery questions and PRD generation | ||
| - Agent status panel verification | ||
|
|
||
| ### 4. `test_complete_user_journey.spec.ts` (1 comprehensive test) | ||
| - Full workflow from login → project creation → discovery → PRD → agent execution | ||
| - Dashboard panel accessibility verification | ||
| - Tab navigation validation | ||
|
|
||
| ## Frontend Changes | ||
|
|
||
| ### Data-testid Attributes Added | ||
|
|
||
| The following components were updated with `data-testid` attributes for stable test selectors: | ||
|
|
||
| **LoginForm.tsx:** | ||
| - `email-input` - Email input field | ||
| - `password-input` - Password input field | ||
| - `login-button` - Login submit button | ||
| - `auth-error` - Authentication error message | ||
|
|
||
| **ProjectCreationForm.tsx:** | ||
| - `project-name-input` - Project name input | ||
| - `project-description-input` - Project description textarea | ||
| - `create-project-submit` - Submit button | ||
| - `form-error` - Validation error messages | ||
|
|
||
| **ProjectList.tsx:** | ||
| - `create-project-button` - Create new project button | ||
| - `project-list` - Projects grid container | ||
|
|
||
| **Navigation.tsx:** | ||
| - `user-menu` - User email display | ||
| - `logout-button` - Logout button | ||
|
|
||
| **DiscoveryProgress.tsx:** | ||
| - `discovery-question` - Current discovery question display | ||
| - `discovery-answer-input` - Answer textarea | ||
| - `submit-answer-button` - Submit answer button | ||
|
|
||
| **Dashboard.tsx:** | ||
| - `prd-generated` - View PRD button (indicates PRD exists) | ||
| - `dashboard-header` - Dashboard header | ||
| - `agent-status-panel` - Agent status panel | ||
| - `metrics-panel` - Cost & metrics panel | ||
| - `review-findings-panel` - Code review findings panel | ||
| - `checkpoint-panel` - Checkpoints panel | ||
| - `nav-menu` - Navigation tabs | ||
| - `overview-tab`, `context-tab`, `checkpoint-tab` - Tab buttons | ||
|
|
||
| ## Test Utilities | ||
|
|
||
| ### Helper Functions (`test-utils.ts`) | ||
|
|
||
| **`loginUser(page, email, password)`** | ||
| - Navigates to /login | ||
| - Fills credentials | ||
| - Submits form | ||
| - Waits for redirect to root/projects page | ||
|
|
||
| **`createTestProject(page, name, description)`** | ||
| - Navigates to root | ||
| - Clicks create project button | ||
| - Fills form with unique timestamped name | ||
| - Returns project ID from URL | ||
|
|
||
| **`answerDiscoveryQuestion(page, answer)`** | ||
| - Waits for discovery input | ||
| - Fills answer | ||
| - Submits | ||
| - Waits for next question or completion | ||
|
|
||
| ## Current Status & Known Issues | ||
|
|
||
| ### ✅ Completed | ||
| - All frontend components have data-testid attributes | ||
| - Test utilities created | ||
| - 4 test spec files with 11 total test cases written | ||
| - Tests properly clear cookies to bypass global setup session | ||
| - TypeScript compilation passes | ||
| - Frontend build succeeds | ||
|
|
||
| ### ⚠️ Known Issue: Next.js Dev Server Timing | ||
|
|
||
| **Problem:** | ||
| Tests are failing with 404 errors when navigating to `/login` and other routes during E2E test execution, even though: | ||
| - Routes exist (`/login/page.tsx`, `/signup/page.tsx`, etc.) | ||
| - Frontend builds successfully in production mode | ||
| - Routes are listed in build output | ||
|
|
||
| **Root Cause:** | ||
| Next.js development server compiles pages on-demand on first request. When tests navigate immediately after server startup, pages haven't been compiled yet, resulting in 404 errors. | ||
|
|
||
| **Evidence:** | ||
| ```markdown | ||
| # error-context.md from test failure | ||
| - generic [active]: | ||
| - main: | ||
| - heading "404" [level=1] | ||
| - heading "This page could not be found." [level=2] | ||
| ``` | ||
|
|
||
| ### Proposed Solutions | ||
|
|
||
| **Option 1: Use Production Build for Tests (Recommended)** | ||
| Modify `playwright.config.ts` webServer config to use production build: | ||
| ```typescript | ||
| webServer: [ | ||
| // Backend | ||
| { ... }, | ||
| // Frontend - production mode | ||
| { | ||
| command: 'cd ../../web-ui && npm run build && npm start', | ||
| url: FRONTEND_URL, | ||
| reuseExistingServer: !process.env.CI, | ||
| timeout: 120000, | ||
| } | ||
| ] | ||
| ``` | ||
|
|
||
| **Option 2: Add Route Pre-warming in Global Setup** | ||
| Add code to `global-setup.ts` to visit all routes once before tests run: | ||
| ```typescript | ||
| const routes = ['/login', '/signup', '/', '/projects/1']; | ||
| for (const route of routes) { | ||
| await page.goto(route); | ||
| await page.waitForLoadState('networkidle'); | ||
| } | ||
| ``` | ||
|
|
||
| **Option 3: Increase Navigation Timeouts** | ||
| Add longer timeouts in tests: | ||
| ```typescript | ||
| await page.goto('/login', { timeout: 30000, waitUntil: 'networkidle' }); | ||
| ``` | ||
|
|
||
| ## Running the Tests | ||
|
|
||
| ### Prerequisites | ||
| 1. Backend server running on port 8080 | ||
| 2. Frontend server running on port 3000 (or production build) | ||
| 3. Test database initialized | ||
|
|
||
| ### Command | ||
| ```bash | ||
| cd tests/e2e | ||
| npx playwright test test_auth_flow.spec.ts test_project_creation.spec.ts test_start_agent_flow.spec.ts test_complete_user_journey.spec.ts --project=chromium | ||
| ``` | ||
|
|
||
| ### CI/CD Considerations | ||
| - Use Option 1 (production builds) for CI environments | ||
| - Ensure sufficient timeout buffers | ||
| - Run tests sequentially (`--workers=1`) to avoid database conflicts | ||
| - Use retries (`--retries=2`) for flaky network conditions | ||
|
|
||
| ## Test Design Principles | ||
|
|
||
| ### UI-Driven vs Database Seeding | ||
| These tests intentionally interact with the actual UI rather than bypassing it through database seeding to: | ||
| - Validate the complete user experience | ||
| - Catch UI regressions and routing issues | ||
| - Test authentication flows end-to-end | ||
| - Ensure forms work as beta testers will use them | ||
|
|
||
| ### Session Management | ||
| Tests clear cookies before execution to: | ||
| - Start from a logged-out state | ||
| - Test actual login flows | ||
| - Avoid conflicts with global setup's pre-seeded session | ||
|
|
||
| ### Unique Project Names | ||
| Projects created during tests use timestamps to: | ||
| - Avoid name conflicts across test runs | ||
| - Enable parallel test execution (future) | ||
| - Simplify test data cleanup | ||
|
|
||
| ## Next Steps | ||
|
|
||
| 1. **Fix Next.js timing issue** - Implement Option 1 (production builds) for reliable test execution | ||
| 2. **Verify all tests pass** - Run full suite across all browsers (Chromium, Firefox, WebKit) | ||
| 3. **Add CI integration** - Update CI workflow to run user journey tests | ||
| 4. **Monitor flakiness** - Track test stability over multiple runs | ||
| 5. **Add test data cleanup** - Implement teardown to remove test projects | ||
|
|
||
| ## Acceptance Criteria Status | ||
|
|
||
| | Criterion | Status | | ||
| |-----------|--------| | ||
| | 4 test files created | ✅ Complete | | ||
| | `test_auth_flow.spec.ts` with 4 tests | ✅ Complete | | ||
| | `test_project_creation.spec.ts` with 3 tests | ✅ Complete | | ||
| | `test_start_agent_flow.spec.ts` with 3 tests | ✅ Complete | | ||
| | `test_complete_user_journey.spec.ts` with 1 test | ✅ Complete | | ||
| | Helper utilities in `test-utils.ts` | ✅ Complete | | ||
| | Tests pass on Chromium, Firefox, WebKit | ⚠️ Blocked by Next.js timing issue | | ||
| | Tests run in CI without flakiness | ⚠️ Pending timing issue fix | | ||
| | Coverage for `/login`, `/`, dashboard flows | ✅ Complete | | ||
|
|
||
| ## Files Modified | ||
|
|
||
| ### Frontend Components | ||
| - `web-ui/src/components/auth/LoginForm.tsx` | ||
| - `web-ui/src/components/ProjectCreationForm.tsx` | ||
| - `web-ui/src/components/ProjectList.tsx` | ||
| - `web-ui/src/components/Navigation.tsx` | ||
| - `web-ui/src/components/DiscoveryProgress.tsx` | ||
| - `web-ui/src/components/Dashboard.tsx` | ||
|
|
||
| ### Test Files (New) | ||
| - `tests/e2e/test_auth_flow.spec.ts` | ||
| - `tests/e2e/test_project_creation.spec.ts` | ||
| - `tests/e2e/test_start_agent_flow.spec.ts` | ||
| - `tests/e2e/test_complete_user_journey.spec.ts` | ||
|
|
||
| ### Test Utilities | ||
| - `tests/e2e/test-utils.ts` (extended) | ||
|
|
||
| ## Documentation | ||
| - `tests/e2e/README-USER-JOURNEY-TESTS.md` (this file) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| /** | ||
| * Temporary authentication bypass for E2E tests. | ||
| * | ||
| * TEMPORARY SOLUTION: This file bypasses the login UI by setting session cookies directly. | ||
| * | ||
| * WHY: Frontend uses BetterAuth (separate schema) while backend uses CodeFRAME auth. | ||
| * E2E tests seed users into CodeFRAME's `users` table, but BetterAuth expects its own `user` table. | ||
| * This mismatch prevents the login UI from working in tests. | ||
| * | ||
| * TRACKING: GitHub issue #158 - Align BetterAuth with CodeFRAME authentication system | ||
| * | ||
| * MIGRATION: Once auth is aligned, replace calls to setTestUserSession() with loginUser() | ||
| * from test-utils.ts. The loginUser() helper is already written and will work once auth is fixed. | ||
| * | ||
| * DELETE THIS FILE after auth alignment is complete. | ||
| */ | ||
|
|
||
| import { Page } from '@playwright/test'; | ||
| import * as fs from 'fs'; | ||
| import * as path from 'path'; | ||
|
|
||
| /** | ||
| * Set test user session cookie to bypass login UI. | ||
| * | ||
| * This function reads the session token created by global-setup.ts (via seed-test-data.py) | ||
| * and sets it as a cookie. This allows tests to skip the login page and go directly to | ||
| * authenticated pages. | ||
| * | ||
| * @param page - Playwright page object | ||
| * | ||
| * @example | ||
| * test.beforeEach(async ({ page }) => { | ||
| * await setTestUserSession(page); | ||
| * // Now authenticated as test@example.com, can navigate to protected pages | ||
| * }); | ||
| */ | ||
| export async function setTestUserSession(page: Page): Promise<void> { | ||
| // Read session token from file created by seed-test-data.py | ||
| const tokenFile = path.join(__dirname, '.codeframe', 'test-session-token.txt'); | ||
|
|
||
| if (!fs.existsSync(tokenFile)) { | ||
| throw new Error( | ||
| `Session token file not found: ${tokenFile}\n` + | ||
| `Ensure global-setup.ts has run successfully and seeded the database.` | ||
| ); | ||
| } | ||
|
|
||
| const sessionToken = fs.readFileSync(tokenFile, 'utf-8').trim(); | ||
|
|
||
| if (!sessionToken) { | ||
| throw new Error('Session token file is empty'); | ||
| } | ||
|
|
||
| // Set CodeFRAME session cookie | ||
| // Note: This bypasses BetterAuth entirely and uses CodeFRAME's backend auth | ||
| await page.context().addCookies([{ | ||
| name: 'session_token', | ||
| value: sessionToken, | ||
| domain: 'localhost', | ||
| path: '/', | ||
| httpOnly: true, | ||
| secure: false, // localhost uses HTTP | ||
| sameSite: 'Lax', | ||
| expires: Math.floor(Date.now() / 1000) + 86400 * 7 // 7 days from now | ||
| }]); | ||
|
|
||
| // For debugging: log that we've set the session | ||
| if (process.env.DEBUG_TESTS) { | ||
| console.log(`[Auth Bypass] Set session cookie: ${sessionToken.substring(0, 20)}...`); | ||
| console.log(`[Auth Bypass] Authenticated as: test@example.com`); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Get test user credentials. | ||
| * | ||
| * Returns the credentials for the test user created by seed-test-data.py. | ||
| * These credentials are currently only used for reference, as we bypass login with cookies. | ||
| * | ||
| * Once auth is aligned (GitHub issue #158), these credentials will be used with | ||
| * the loginUser() helper from test-utils.ts. | ||
| */ | ||
| export function getTestUserCredentials() { | ||
| return { | ||
| email: 'test@example.com', | ||
| password: 'testpassword123', | ||
| }; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.