From baa3beccc46dec852f693b40440fba6af793e1fe Mon Sep 17 00:00:00 2001 From: perf3ct Date: Sun, 6 Jul 2025 05:59:52 +0000 Subject: [PATCH] fix(tests): actually make playwright login --- frontend/e2e/auth.spec.ts | 22 +++++++------- frontend/e2e/dashboard.spec.ts | 53 +++++++++++++++++++++++++++++++++ frontend/e2e/fixtures/auth.ts | 33 ++++++++++++-------- frontend/e2e/navigation.spec.ts | 9 +++++- 4 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 frontend/e2e/dashboard.spec.ts diff --git a/frontend/e2e/auth.spec.ts b/frontend/e2e/auth.spec.ts index f24d144..dbb0e67 100644 --- a/frontend/e2e/auth.spec.ts +++ b/frontend/e2e/auth.spec.ts @@ -11,8 +11,8 @@ test.describe('Authentication', () => { await page.goto('/'); // Check for login form elements using Material-UI structure - await expect(page.locator('input[name="username"]')).toBeVisible(); - await expect(page.locator('input[name="password"]')).toBeVisible(); + await expect(page.locator('input[type="text"]').first()).toBeVisible(); + await expect(page.locator('input[type="password"]').first()).toBeVisible(); await expect(page.locator('button[type="submit"]')).toBeVisible(); }); @@ -21,18 +21,18 @@ test.describe('Authentication', () => { await authHelper.loginAs(TEST_CREDENTIALS.admin); - // Should redirect to dashboard or main page - await page.waitForURL(/\/dashboard|\//, { timeout: TIMEOUTS.navigation }); + // Should redirect to dashboard + await page.waitForURL(/.*\/dashboard.*/, { timeout: TIMEOUTS.navigation }); - // Verify we're no longer on login page - await expect(page.locator('input[name="username"]')).not.toBeVisible(); + // Verify we're logged in by checking for welcome message + await expect(page.locator('h4:has-text("Welcome back,")')).toBeVisible(); }); test('should show error with invalid credentials', async ({ page }) => { await page.goto('/'); - await page.fill('input[name="username"]', 'invaliduser'); - await page.fill('input[name="password"]', 'wrongpassword'); + await page.fill('input[type="text"]', 'invaliduser'); + await page.fill('input[type="password"]', 'wrongpassword'); await page.click('button[type="submit"]'); @@ -40,7 +40,7 @@ test.describe('Authentication', () => { await expect(page.locator('.MuiAlert-root, [role="alert"]')).toBeVisible({ timeout: TIMEOUTS.api }); // Should remain on login page - await expect(page.locator('input[name="username"]')).toBeVisible(); + await expect(page.locator('input[type="text"]')).toBeVisible(); }); test.skip('should logout successfully', async ({ page }) => { @@ -90,8 +90,8 @@ test.describe('Authentication', () => { await page.click('button[type="submit"]'); // Should show validation errors or prevent submission - const usernameInput = page.locator('input[name="username"]'); - const passwordInput = page.locator('input[name="password"]'); + const usernameInput = page.locator('input[type="text"]'); + const passwordInput = page.locator('input[type="password"]'); // Check for HTML5 validation or custom validation messages await expect(usernameInput).toBeVisible(); diff --git a/frontend/e2e/dashboard.spec.ts b/frontend/e2e/dashboard.spec.ts new file mode 100644 index 0000000..caf19d3 --- /dev/null +++ b/frontend/e2e/dashboard.spec.ts @@ -0,0 +1,53 @@ +import { test, expect } from './fixtures/auth'; +import { TEST_CREDENTIALS } from './fixtures/auth'; + +test.describe('Dashboard', () => { + test('should display welcome back message after login', async ({ authenticatedPage: page }) => { + // Navigate to dashboard + await page.goto('/dashboard'); + await page.waitForLoadState('networkidle'); + + // Check for welcome message + await expect(page.locator('h4:has-text("Welcome back,")')).toBeVisible(); + + // Check for username in welcome message + await expect(page.locator(`h4:has-text("Welcome back, ${TEST_CREDENTIALS.admin.username}!")`)).toBeVisible(); + }); + + test('should display dashboard stats', async ({ authenticatedPage: page }) => { + await page.goto('/dashboard'); + await page.waitForLoadState('networkidle'); + + // Check for stats cards + await expect(page.locator('text="Total Documents"')).toBeVisible(); + await expect(page.locator('text="Storage Used"')).toBeVisible(); + await expect(page.locator('text="OCR Processed"')).toBeVisible(); + await expect(page.locator('text="Searchable"')).toBeVisible(); + }); + + test('should display quick actions', async ({ authenticatedPage: page }) => { + await page.goto('/dashboard'); + await page.waitForLoadState('networkidle'); + + // Check for quick action buttons + await expect(page.locator('text="Upload Documents"')).toBeVisible(); + await expect(page.locator('text="Search Library"')).toBeVisible(); + await expect(page.locator('text="Browse Documents"')).toBeVisible(); + }); + + test('should have working navigation', async ({ authenticatedPage: page }) => { + await page.goto('/dashboard'); + await page.waitForLoadState('networkidle'); + + // Test navigation to different pages + await page.click('text="Upload Documents"'); + await page.waitForURL(/.*\/upload.*/, { timeout: 5000 }); + + // Go back to dashboard + await page.goto('/dashboard'); + await page.waitForLoadState('networkidle'); + + // Verify we're back on dashboard + await expect(page.locator('h4:has-text("Welcome back,")')).toBeVisible(); + }); +}); \ No newline at end of file diff --git a/frontend/e2e/fixtures/auth.ts b/frontend/e2e/fixtures/auth.ts index ebff3ce..2acee23 100644 --- a/frontend/e2e/fixtures/auth.ts +++ b/frontend/e2e/fixtures/auth.ts @@ -36,17 +36,25 @@ export class AuthHelper { await this.page.goto('/'); await this.page.waitForLoadState('networkidle'); - // Check if already logged in - const usernameInput = await this.page.locator('input[name="username"]').isVisible().catch(() => false); + // Check if already logged in by looking for dashboard content + const welcomeText = await this.page.locator('h4:has-text("Welcome back,")').isVisible().catch(() => false); - if (!usernameInput) { - console.log('Already logged in or no login form found'); + if (welcomeText) { + console.log('Already logged in - found welcome message'); return; } + // Look for login form - Material-UI TextFields with labels + const usernameField = this.page.locator('input[data-testid="username"], input[label="Username"], input[placeholder="Username"], input[type="text"]').first(); + const passwordField = this.page.locator('input[data-testid="password"], input[label="Password"], input[placeholder="Password"], input[type="password"]').first(); + + // Wait for login form to be visible + await usernameField.waitFor({ state: 'visible', timeout: TIMEOUTS.login }); + await passwordField.waitFor({ state: 'visible', timeout: TIMEOUTS.login }); + // Fill login form - await this.page.fill('input[name="username"]', credentials.username); - await this.page.fill('input[name="password"]', credentials.password); + await usernameField.fill(credentials.username); + await passwordField.fill(credentials.password); // Wait for login API response const loginPromise = this.page.waitForResponse(response => @@ -54,17 +62,18 @@ export class AuthHelper { { timeout: TIMEOUTS.login } ); + // Click submit button await this.page.click('button[type="submit"]'); try { await loginPromise; console.log(`Login as ${credentials.username} successful`); - // Wait for navigation away from login page - await this.page.waitForFunction(() => - !window.location.pathname.includes('/login'), - { timeout: TIMEOUTS.navigation } - ); + // Wait for navigation to dashboard + await this.page.waitForURL(/.*\/dashboard.*/, { timeout: TIMEOUTS.navigation }); + + // Verify login by checking for welcome message + await this.page.waitForSelector('h4:has-text("Welcome back,")', { timeout: TIMEOUTS.navigation }); console.log('Navigation completed to:', this.page.url()); } catch (error) { @@ -93,7 +102,7 @@ export class AuthHelper { await this.page.waitForLoadState('networkidle'); // If we see a login form, we're already logged out - const usernameInput = await this.page.locator('input[name="username"]').isVisible().catch(() => false); + const usernameInput = await this.page.locator('input[type="text"], input[data-testid="username"]').isVisible().catch(() => false); if (usernameInput) { return; } diff --git a/frontend/e2e/navigation.spec.ts b/frontend/e2e/navigation.spec.ts index ae3dfbc..b899ff1 100644 --- a/frontend/e2e/navigation.spec.ts +++ b/frontend/e2e/navigation.spec.ts @@ -51,11 +51,15 @@ test.describe('Navigation', () => { }); test('should check what elements are on dashboard', async ({ authenticatedPage: page }) => { - await page.goto('/'); + await page.goto('/dashboard'); await page.waitForLoadState('networkidle', { timeout: 5000 }); console.log('Dashboard URL:', page.url()); + // Check for welcome message + const welcomeMessage = await page.locator('h4:has-text("Welcome back,")').isVisible(); + console.log('Welcome message present:', welcomeMessage); + // Check for common navigation elements const navLinks = await page.locator('a, button').allTextContents(); console.log('Navigation elements:', navLinks); @@ -68,5 +72,8 @@ test.describe('Navigation', () => { const uploadTexts = await page.locator(':has-text("Upload"), :has-text("File")').allTextContents(); console.log('Upload-related text:', uploadTexts); } + + // Verify we're properly logged in + await expect(page.locator('h4:has-text("Welcome back,")')).toBeVisible(); }); }); \ No newline at end of file