Implement comprehensive frontend integration testing with Playwright
- Add Playwright E2E testing framework with cross-browser support (Chrome, Firefox) - Create authentication helpers for CalDAV server integration - Implement calendar interaction helpers with event creation, drag-and-drop, and view switching - Add comprehensive drag-and-drop test suite with event cleanup - Configure CI/CD integration with Gitea Actions for headless testing - Support both local development and CI environments with proper dependency management - Include video recording, screenshots, and HTML reporting for test debugging - Handle Firefox-specific timing and interaction challenges with force clicks and timeouts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
63
frontend/e2e/helpers/auth-helpers.ts
Normal file
63
frontend/e2e/helpers/auth-helpers.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Page, expect } from '@playwright/test';
|
||||
|
||||
export class AuthHelpers {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
async loginWithTestCredentials() {
|
||||
await this.page.goto('/login');
|
||||
|
||||
// Use environment variables for test credentials
|
||||
const serverUrl = process.env.TEST_CALDAV_SERVER || 'https://baikal.rcjohnstone.com/dav.php/';
|
||||
const username = process.env.TEST_CALDAV_USERNAME || 'test';
|
||||
const password = process.env.TEST_CALDAV_PASSWORD || 'I0W?7`|Cs6tA`s';
|
||||
|
||||
await this.page.getByLabel('CalDAV Server URL').fill(serverUrl);
|
||||
await this.page.getByRole('textbox', { name: 'Username' }).fill(username);
|
||||
await this.page.getByLabel('Password').fill(password);
|
||||
|
||||
await this.page.getByRole('button', { name: 'Sign In' }).click();
|
||||
|
||||
// Wait for login to complete - either success (redirect) or error message
|
||||
await Promise.race([
|
||||
this.page.waitForURL(/.*\/calendar/, { timeout: 10000 }),
|
||||
this.page.locator('.error-message').waitFor({ state: 'visible', timeout: 10000 })
|
||||
]);
|
||||
|
||||
// If we're on the calendar page, verify the interface loaded
|
||||
if (this.page.url().includes('/calendar') || (!this.page.url().includes('/login'))) {
|
||||
await expect(this.page.locator('.calendar-grid').or(this.page.locator('.sidebar'))).toBeVisible({ timeout: 5000 });
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
// Look for logout button in sidebar - it might be text or button
|
||||
const logoutButton = this.page.locator('text=Logout').or(this.page.getByRole('button', { name: 'Logout' }));
|
||||
await logoutButton.click();
|
||||
|
||||
// Should redirect to login page
|
||||
await expect(this.page).toHaveURL(/.*\/login/);
|
||||
}
|
||||
|
||||
async isLoggedIn(): Promise<boolean> {
|
||||
try {
|
||||
// Check if we're on the calendar page
|
||||
const currentUrl = this.page.url();
|
||||
if (!currentUrl.includes('/calendar') && !currentUrl.includes('/') || currentUrl.includes('/login')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look for calendar interface elements instead of user-info
|
||||
await expect(this.page.locator('.calendar-grid').or(this.page.locator('.sidebar'))).toBeVisible({ timeout: 5000 });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async ensureLoggedIn() {
|
||||
const loggedIn = await this.isLoggedIn();
|
||||
if (!loggedIn) {
|
||||
await this.loginWithTestCredentials();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user